def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var cur2id
-
-
-
-Source code
-
@property
-def cur2id(self):
- if not self._cur2id:
- self._cur2id = dict(zip(self.id2cur.values(), self.id2cur.keys()))
- return self._cur2id
-
-
-
var cur2usd
-
-
e.g. AED = 3,672 means 3,6… times AED=1 USD
-
-Source code
-
@property
-def cur2usd(self):
- """
- e.g. AED = 3,672 means 3,6... times AED=1 USD
- """
- if not self._data_cur:
- self.load()
- return self._data_cur
-
-
-
var id2cur
-
-
-
-Source code
-
@property
-def id2cur(self):
- if not self._id2cur:
- self._id2cur = CURRNECIES_IDS
- return self._id2cur
-
-
-
var name
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
-
Methods
-
-
-def cur2id_print(self)
-
-
-
-
-Source code
-
def cur2id_print(self):
- pprint(self.cur2id)
-
-
-
-def cur2usd_print(self)
-
-
-
-
-Source code
-
def cur2usd_print(self):
- print(self.cur2usd)
-
-
-
-def id2cur_print(self)
-
-
-
-
-Source code
-
def id2cur_print(self):
- pprint(self.id2cur)
-
-
-
-def load(self)
-
-
-
-
-Source code
-
def load(self):
- # data = self._cache.get("currency_data", get, expire=3600 * 24)
- data = get_currency_data(self.api_key, fake=False)
- self._data_cur = data
-
-
-
-def test(self)
-
-
-
-
-Source code
-
def test(self):
- self._log_info(self.cur2usd)
- assert "aed" in self.cur2usd
This module is used to manage your digital ocean account, create droplet,list all the droplets, destroy droplets, create project, list all the projects and delete project
In the below examples, I have supposed that you followed the above steps
-and you got digital ocean client with the name (dg)
-
-Source code
-
"""This module is used to manage your digital ocean account, create droplet,list all the droplets, destroy droplets, create project, list all the projects and delete project
-# prerequisites
- ## Sshkey client and loaded with you public key
-'''python
-ssh = j.clients.sshkey.get(name= "test")
-ssh.private_key_path = "/home/rafy/.ssh/id_rsa"
-ssh.load_from_file_system()
-'''
-## Create Digital Ocean client and set your token and load your sshkey
-```python
-dg = j.clients.digitalocean.get("testDG")
-dg.token_ = ""
-```
-## Set sshclient you have created
-``` python
-dg.set_default_sshkey(ssh)
-```
-## Use Digital Ocean client
-
-### Create and deploy Project to Digital Ocean
-
-#### Create Project (name must not contian spaces or start with number)
-``` python
- project = dg.projects.new("test_DG_client")
-```
-#### Set the name you want to deploy with on Digital Ocean
-``` python
-project.set_digital_ocean_name("test project DO client")
-```
-#### Deploy the project (you have to specific the purpose)
-``` python
-project.deploy(purpose="testing digital ocean client")
-```
-#### Delete the project from Digital Ocean
-``` python
-project.delete_remote()
-```
-
-### Create and deploy Droplet to Digital Ocean
-
-#### Create Droplet (name must not contian spaces or start with number)
-``` python
-droplet = dg.droplets.new("test_droplet_dg")
-```
-#### Set the name you want to deploy with on Digital Ocean
-``` python
-droplet.set_digital_ocean_name("droplet-test-DO")
-```
-#### Deploy the Droplet
-```python
-droplet.deploy()
-```
-#### Delete the Droplet from Digital Ocean
-```python
-droplet.delete_remote()
-```
-
-### Get digital ocean regions
-```python
-dg.regions
-```
-
-### Get digital ocean images
-```python
-dg.images
-```
-
-In the below examples, I have supposed that you followed the above steps
-and you got digital ocean client with the name (dg)
-"""
-
-from jumpscale.loader import j
-from jumpscale.clients.base import Client
-from jumpscale.core.base import fields
-from jumpscale.core.base import StoredFactory
-from .project import ProjectManagement
-import digitalocean
-
-
-class ProjectFactory(StoredFactory):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def list_remote(self):
- """
- Returns list of projects on Digital Ocean
-
- e.g
- dg.projects.list_remote() -> list of projects
-
- Returns
- list(projects): list of projects on digital ocean
-
- """
- return ProjectManagement.list(self.parent_instance.client)
-
- def check_project_exist_remote(self, name):
- """
- Check a project with specific name exits on Digital Ocean
-
- e.g
- dg.projects.check_project_exist_remote("codescalers") -> True
- dg.projects.check_project_exist_remote("dsrfjsdfjl") -> False
-
- Args
- name (str): name of the project
-
- Returns
- bool : True if the project exits and False if the project does not exist on digital ocean
- """
- for project in self.list_remote():
- if project.name == name:
- return True
- return False
-
- def get_project_exist_remote(self, name):
- """
- Get a project with specifc name from Digital Ocean.
-
- e.g
- dg.projects.get_project_exist_remote("codescalers") -> project
-
- Args
- name (str): name of the project
-
- Returns
- Project : a project from digital ocean with the name specified
- """
- for project in self.list_remote():
- if project.name == name:
- return project
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
-
-
-class Project(Client):
- do_name = fields.String()
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def set_digital_ocean_name(self, name):
- """Set a name for your project to be used on Digital Ocean
- e.g
- project.set_digital_ocean_name("test project DO client")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
-
- def get_digital_ocean_name(self):
- """Get a name for the project which is used on digital ocean
- e.g
- project.get_digital_ocean_name() -> "test project DO client"
-
- Returns:
- str: name for the project which is used on digital ocean
- """
- return self.do_name
-
- def deploy(self, purpose, description="", environment="", is_default=False):
- """Create a digital ocean project
- e.g
- project.deploy(purpose="testing digital ocean client") -> project
- Args:
- purpose(str): purpose of the project (not optional)
- description(str): description of the project, defaults to ""
- environment(str): environment of project's resources, defaults to ""
- is_default(bool): make this the default project for your user
-
- Returns:
- project: The project object that has been created
- """
-
- if self.parent.projects.check_project_exist_remote(self.do_name):
- raise j.exceptions.Value("A project with the same name already exists")
-
- project = ProjectManagement(
- token=self.parent.projects.parent_instance.token_,
- name=self.do_name,
- purpose=purpose,
- description=description,
- environment=environment,
- is_default=is_default,
- )
- project.create()
-
- if is_default:
- project.update(is_default=True)
-
- return project
-
- def delete_remote(self):
- """Delete the project from Digital Ocean (A project can't be deleted unless it has no resources.)
-
- e.g
- project.delete_remote()
- """
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- project.delete()
-
-
-class DropletFactory(StoredFactory):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def list_remote(self, project_name=None):
- """
- List all remote droplet or list droplets for a project if it is specified
-
- e.g
- dg.droplets.list_remote() -> list of droplets
- dg.droplets.list_remote("codescalers") -> list of droplets on codescalers project
-
- Args:
- project_name (str) : name of project on digital ocean (optional)
-
- Returns
- list (Droplet) : list of droplets on digital ocean
-
-
- """
- if project_name:
- project = self.parent_instance.projects.get_project_exist_remote(project_name)
- return project.list_droplets()
-
- return self.parent_instance.client.get_all_droplets()
-
- def check_droplet_exist_remote(self, name):
- """
- Check droplet exists on digital ocean
-
- e.g
- dg.droplets.check_droplet_exist_remote("3git") -> True
- dg.droplets.check_droplet_exist_remote("sdfgdfed") -> False
-
- Args:
- name (str) : name of droplet
-
- Returns
- bool : True if the droplet exist or False if the droplet does not exist
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return True
- return False
-
- def get_droplet_exist_remote(self, name):
- """
- Get Droplet exists from Digital Ocean
-
- e.g
- dg.droplets.get_droplet_exist_remote("3git")
-
- Args:
- name (str) : name of droplet
-
- Returns
- droplet : droplet with the name specified
-
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return droplet
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
-
- def shutdown_all(self, project_name=None):
- """
- Shutdown all the droplets or droplets in specific project
-
- e.g
- dg.droplets.shutdown_all("codescalers")
- dg.droplets.shutdown_all()
-
- Args:
- name (str) : name of the project
-
- """
- for droplet in self.list_remote(project_name):
- droplet.shutdown()
-
- def delete_all(self, ignore=None, interactive=True, project_name=None):
- """
- Delete all the droplets or delete all the droplets in specific project
-
- e.g
- dg.droplets.delete_all(project_name = "codescalers")
- dg.droplets.delete_all()
-
- Args:
- project_name (str) : name of the project
- ignore (list): list of ignored droplets to prevent their deletion
- interactive (bool): if True the deletion will be interactive and
- confirm if you want to delete but if False it
- will delete directly
- """
- if not ignore:
- ignore = []
-
- def test(ignore, name):
- if name.startswith("TF-"):
- return False
- for item in ignore:
- if name.lower().find(item.lower()) != -1:
- return False
- return True
-
- todo = []
- for droplet in self.list_remote(project_name):
- if test(ignore, droplet.name):
- todo.append(droplet)
- if todo != []:
- todotxt = ",".join([i.name for i in todo])
- if not interactive or j.tools.console.ask_yes_no("ok to delete:%s" % todotxt):
- for droplet in todo:
- droplet.destroy()
-
-
-class Droplet(Client):
- do_name = fields.String()
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def set_digital_ocean_name(self, name):
- """Set a name for your Droplet to be used on Digital Ocean
-
- e.g
- droplet.set_digital_ocean_name("test-name")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
-
- def get_digital_ocean_name(self):
- """Get a name for the Droplet which is used on digital ocean
-
- e.g
- droplet.get_digital_ocean_name() -> "test-name"
-
- Returns
- str: name for the droplet which is used on digital ocean
- """
- return self.do_name
-
- def deploy(
- self,
- sshkey=None,
- region="Amsterdam 3",
- image="ubuntu 18.04",
- size_slug="s-1vcpu-2gb",
- delete=True,
- project_name=None,
- ):
- """
- Deploy your Droplet to Digital Ocean
-
- Args
- sshkey (string): sshkey name used on digital ocean (if not set it will use the default one which already loaded)
- region (string): region name to deploy to
- image (string): Image name to be used
- size_slug (string): size of the droplet (s-1vcpu-2gb,s-6vcpu-16gb,gd-8vcpu-32gb)
- delete (bool): delete the droplet if it is already deployed on digital ocean
- project_name (string): project to add this droplet it. If not specified the default project will be used.
-
- """
- project = None
- if project_name:
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- if not project:
- raise j.exceptions.Input("could not find project with name:%s" % project_name)
-
- # Get ssh
- if not sshkey:
- sshkey_do = self.parent.get_default_sshkey()
-
- if not sshkey_do:
- # means we did not find the sshkey on digital ocean yet, need to create
- sshkey = self.parent.sshkey
- key = digitalocean.SSHKey(
- token=self.parent.projects.parent_instance.token_, name=sshkey.name, public_key=sshkey.public_key
- )
- key.create()
- sshkey_do = self.parent.get_default_sshkey()
- assert sshkey_do
- sshkey = sshkey_do.name
-
- if self.parent.droplets.check_droplet_exist_remote(self.do_name):
- dr0 = self.parent.droplets.get_droplet_exist_remote(self.do_name)
- if delete:
- dr0.destroy()
- else:
- sshcl = j.clients.sshclient.get(name="do_%s" % self.do_name, host=dr0.ip_address, sshkey=sshkey)
- return dr0, sshcl
-
- sshkey = self.parent.droplets.parent_instance.get_sshkey(sshkey)
- region = self.parent.droplets.parent_instance.get_region(region)
- imagedo = self.parent.droplets.parent_instance.get_image(image)
-
- img_slug_or_id = imagedo.slug if imagedo.slug else imagedo.id
-
- droplet = digitalocean.Droplet(
- token=self.parent.droplets.parent_instance.token_,
- name=self.do_name,
- region=region.slug,
- image=img_slug_or_id,
- size_slug=size_slug,
- ssh_keys=[sshkey],
- backups=False,
- )
- droplet.create()
-
- if project:
- project.assign_resources(["do:droplet:%s" % droplet.id])
-
- def delete_remote(self):
- """Delete Droplet from digital ocean
-
- e.g
- droplet.delete_remote()
-
- """
- droplet = self.parent.droplets.get_droplet_exist_remote(self.do_name)
- droplet.destroy()
-
-
-class DigitalOcean(Client):
- name = fields.String()
- token_ = fields.String()
- projects = fields.Factory(Project, factory_type=ProjectFactory)
- droplets = fields.Factory(Droplet, factory_type=DropletFactory)
-
- def __init__(self):
- super().__init__()
- self._client = None
-
- @property
- def client(self):
- """Return a new client if it is not set or it will return the already existed one
-
- e.g
- dg.client -> <Manager>
- Returns
- Manager: client form digital ocean manager
- """
-
- if not self._client:
- self._client = digitalocean.Manager(token=self.token_)
- return self._client
-
- # Images
- @property
- def images(self):
- """Return a list of digital ocean availabe images
-
- e.g
- dg.images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean available
- """
- return self.client.get_distro_images()
-
- @property
- def myimages(self):
- """Return a list of digital ocean images, you have created
-
- e.g
- dg.myimages -> [<Image: 48614453 Unknown Zero_OS>,
- <Image: 50898718 Ubuntu JumpScale>,...]
-
- Returns
- List : list of images on digital ocean, you have created
- """
- return self.client.get_images(private=True)
-
- @property
- def account_images(self):
- """Return a list of digital ocean images and the images you have created
-
- e.g
- dg.account_images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean images and the images you have created
- """
-
- return self.images + self.myimages
-
- def get_image(self, name):
- """Return an image
-
- e.g
- dg.get_image(name="CentOS") -> <Image: 31354013 CentOS 6.9 x32>
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images on digital ocean images and the images you have created
- """
- for item in self.account_images:
- if item.description:
- name_do1 = item.description.lower()
- else:
- name_do1 = ""
- name_do2 = item.distribution + " " + item.name
- print(f" - {name_do1}--{name_do2}")
- if name_do1.lower().find(name.lower()) != -1 or name_do2.lower().find(name.lower()) != -1:
- return item
- raise j.exceptions.Base("did not find image:%s" % name)
-
- def get_image_names(self, name=""):
- """ Return all the image or images with a specified name
- e.g
- dg.get_image_names() -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602',...]
- dg.get_image_names("centos") -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602']
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images
- """
- res = []
- name = name.lower()
- for item in self.images:
- if item.description:
- name_do = item.description.lower()
- else:
- name_do = item.distribution + " " + item.name
- if name_do.find(name) != -1:
- res.append(name_do)
- return res
-
- # Size
-
- @property
- def sizes(self):
- """Return a list sizes available on digital ocean
-
- e.g
- dg.sizes -> [s-1vcpu-1gb, 512mb, s-1vcpu-2gb, 1gb, s-3vcpu-1gb,.....]
-
- Returns
- List : list of sizes
- """
- return self.client.get_all_sizes()
-
- # Regions
-
- @property
- def regions(self):
- """Return a list regions available on digital ocean
-
- e.g
- dg.regions -> [<Region: nyc1 New York 1>, <Region: sgp1 Singapore 1>,...]
-
- Returns
- List : list of regions
- """
- return self.client.get_all_regions()
-
- @property
- def region_names(self):
- """Returns Digital Ocean regions
-
- e.g
- dg.region_names -> ['nyc1', 'sgp1', 'lon1', 'nyc3', 'ams3', 'fra1', 'tor1', 'sfo2', 'blr1']
-
- Returns
- list : list of digital ocean regions
- """
- return [i.slug for i in self.regions]
-
- def get_region(self, name):
- """
- Returns specific region
-
- e.g
- dg.get_region(name = 'nyc1') -> <Region: nyc1 New York 1>
-
- Args
- name (str) : name of the required region
- Returns
- Region : the region with the name specified
- """
- for item in self.regions:
- if name == item.slug:
- return item
- if name == item.name:
- return item
- raise j.exceptions.Base("did not find region:%s" % name)
-
- # SSHkeys
- @property
- def sshkeys(self):
- """
- Return list of sshkeys on digital ocean
-
- e.g
- dg.sshkeys -> [<SSHKey: 25882170 3bot_container_sandbox>,
- <SSHKey: 27130645 Geert-root>,...]
-
- Returns
- list : list of sshkeys
- """
-
- return self.client.get_all_sshkeys()
-
- def get_default_sshkey(self):
- """
- Return sshkey you have added to your Digital Ocean client
-
- e.g
- dg.get_default_sshkey() -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Returns
- list : list of sshkeys
- """
- pubkeyonly = self.sshkey.public_key
- for item in self.sshkeys:
- if item.public_key.find(pubkeyonly) != -1:
- return item
- return None
-
- def set_default_sshkey(self, default_sshkey):
- """
- Set sshkey you Digital Ocean client
-
- e.g
- dg.set_default_sshkey(ssh) -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Args
- default_sshkey (SSHKeyClient) : sshkey client you have created
- """
- self.sshkey = default_sshkey
-
- def get_sshkey(self, name):
- """
- get sshkey from Digital Ocean
-
- e.g
- dg.get_sshkey("rafy@rafy-Inspiron-3576") -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Args
- name (string) : sshkey name
-
- Returns
- SSHKey : return the specified sshkey
- """
- for item in self.sshkeys:
- if name == item.name:
- return item
- raise j.exceptions.Base("did not find key:%s" % name)
-
- def __str__(self):
- return "digital ocean client:%s" % self.name
-
- __repr__ = __str__
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class DigitalOcean
-
-
-
A simple attribute-based namespace.
-
SimpleNamespace(**kwargs)
-
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class DigitalOcean(Client):
- name = fields.String()
- token_ = fields.String()
- projects = fields.Factory(Project, factory_type=ProjectFactory)
- droplets = fields.Factory(Droplet, factory_type=DropletFactory)
-
- def __init__(self):
- super().__init__()
- self._client = None
-
- @property
- def client(self):
- """Return a new client if it is not set or it will return the already existed one
-
- e.g
- dg.client -> <Manager>
- Returns
- Manager: client form digital ocean manager
- """
-
- if not self._client:
- self._client = digitalocean.Manager(token=self.token_)
- return self._client
-
- # Images
- @property
- def images(self):
- """Return a list of digital ocean availabe images
-
- e.g
- dg.images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean available
- """
- return self.client.get_distro_images()
-
- @property
- def myimages(self):
- """Return a list of digital ocean images, you have created
-
- e.g
- dg.myimages -> [<Image: 48614453 Unknown Zero_OS>,
- <Image: 50898718 Ubuntu JumpScale>,...]
-
- Returns
- List : list of images on digital ocean, you have created
- """
- return self.client.get_images(private=True)
-
- @property
- def account_images(self):
- """Return a list of digital ocean images and the images you have created
-
- e.g
- dg.account_images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean images and the images you have created
- """
-
- return self.images + self.myimages
-
- def get_image(self, name):
- """Return an image
-
- e.g
- dg.get_image(name="CentOS") -> <Image: 31354013 CentOS 6.9 x32>
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images on digital ocean images and the images you have created
- """
- for item in self.account_images:
- if item.description:
- name_do1 = item.description.lower()
- else:
- name_do1 = ""
- name_do2 = item.distribution + " " + item.name
- print(f" - {name_do1}--{name_do2}")
- if name_do1.lower().find(name.lower()) != -1 or name_do2.lower().find(name.lower()) != -1:
- return item
- raise j.exceptions.Base("did not find image:%s" % name)
-
- def get_image_names(self, name=""):
- """ Return all the image or images with a specified name
- e.g
- dg.get_image_names() -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602',...]
- dg.get_image_names("centos") -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602']
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images
- """
- res = []
- name = name.lower()
- for item in self.images:
- if item.description:
- name_do = item.description.lower()
- else:
- name_do = item.distribution + " " + item.name
- if name_do.find(name) != -1:
- res.append(name_do)
- return res
-
- # Size
-
- @property
- def sizes(self):
- """Return a list sizes available on digital ocean
-
- e.g
- dg.sizes -> [s-1vcpu-1gb, 512mb, s-1vcpu-2gb, 1gb, s-3vcpu-1gb,.....]
-
- Returns
- List : list of sizes
- """
- return self.client.get_all_sizes()
-
- # Regions
-
- @property
- def regions(self):
- """Return a list regions available on digital ocean
-
- e.g
- dg.regions -> [<Region: nyc1 New York 1>, <Region: sgp1 Singapore 1>,...]
-
- Returns
- List : list of regions
- """
- return self.client.get_all_regions()
-
- @property
- def region_names(self):
- """Returns Digital Ocean regions
-
- e.g
- dg.region_names -> ['nyc1', 'sgp1', 'lon1', 'nyc3', 'ams3', 'fra1', 'tor1', 'sfo2', 'blr1']
-
- Returns
- list : list of digital ocean regions
- """
- return [i.slug for i in self.regions]
-
- def get_region(self, name):
- """
- Returns specific region
-
- e.g
- dg.get_region(name = 'nyc1') -> <Region: nyc1 New York 1>
-
- Args
- name (str) : name of the required region
- Returns
- Region : the region with the name specified
- """
- for item in self.regions:
- if name == item.slug:
- return item
- if name == item.name:
- return item
- raise j.exceptions.Base("did not find region:%s" % name)
-
- # SSHkeys
- @property
- def sshkeys(self):
- """
- Return list of sshkeys on digital ocean
-
- e.g
- dg.sshkeys -> [<SSHKey: 25882170 3bot_container_sandbox>,
- <SSHKey: 27130645 Geert-root>,...]
-
- Returns
- list : list of sshkeys
- """
-
- return self.client.get_all_sshkeys()
-
- def get_default_sshkey(self):
- """
- Return sshkey you have added to your Digital Ocean client
-
- e.g
- dg.get_default_sshkey() -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Returns
- list : list of sshkeys
- """
- pubkeyonly = self.sshkey.public_key
- for item in self.sshkeys:
- if item.public_key.find(pubkeyonly) != -1:
- return item
- return None
-
- def set_default_sshkey(self, default_sshkey):
- """
- Set sshkey you Digital Ocean client
-
- e.g
- dg.set_default_sshkey(ssh) -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Args
- default_sshkey (SSHKeyClient) : sshkey client you have created
- """
- self.sshkey = default_sshkey
-
- def get_sshkey(self, name):
- """
- get sshkey from Digital Ocean
-
- e.g
- dg.get_sshkey("rafy@rafy-Inspiron-3576") -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Args
- name (string) : sshkey name
-
- Returns
- SSHKey : return the specified sshkey
- """
- for item in self.sshkeys:
- if name == item.name:
- return item
- raise j.exceptions.Base("did not find key:%s" % name)
-
- def __str__(self):
- return "digital ocean client:%s" % self.name
-
- __repr__ = __str__
Return a list of digital ocean images and the images you have created
-
e.g
-dg.account_images
--> [,
-,…]
-
Returns
-List : list of images on digital ocean images and the images you have created
-
-Source code
-
@property
-def account_images(self):
- """Return a list of digital ocean images and the images you have created
-
- e.g
- dg.account_images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean images and the images you have created
- """
-
- return self.images + self.myimages
-
-
-
var client
-
-
Return a new client if it is not set or it will return the already existed one
-
e.g
-dg.client
-->
-Returns
-Manager: client form digital ocean manager
-
-Source code
-
@property
-def client(self):
- """Return a new client if it is not set or it will return the already existed one
-
- e.g
- dg.client -> <Manager>
- Returns
- Manager: client form digital ocean manager
- """
-
- if not self._client:
- self._client = digitalocean.Manager(token=self.token_)
- return self._client
-
-
-
var droplets
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var images
-
-
Return a list of digital ocean availabe images
-
e.g
-dg.images
--> [,
-,…]
-
Returns
-List : list of images on digital ocean available
-
-Source code
-
@property
-def images(self):
- """Return a list of digital ocean availabe images
-
- e.g
- dg.images -> [<Image: 31354013 CentOS 6.9 x32>,
- <Image: 34902021 CentOS 6.9 x64>,...]
-
- Returns
- List : list of images on digital ocean available
- """
- return self.client.get_distro_images()
-
-
-
var myimages
-
-
Return a list of digital ocean images, you have created
-
e.g
-dg.myimages
--> [,
-,…]
-
Returns
-List : list of images on digital ocean, you have created
-
-Source code
-
@property
-def myimages(self):
- """Return a list of digital ocean images, you have created
-
- e.g
- dg.myimages -> [<Image: 48614453 Unknown Zero_OS>,
- <Image: 50898718 Ubuntu JumpScale>,...]
-
- Returns
- List : list of images on digital ocean, you have created
- """
- return self.client.get_images(private=True)
-
-
-
var name
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var projects
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
@property
-def region_names(self):
- """Returns Digital Ocean regions
-
- e.g
- dg.region_names -> ['nyc1', 'sgp1', 'lon1', 'nyc3', 'ams3', 'fra1', 'tor1', 'sfo2', 'blr1']
-
- Returns
- list : list of digital ocean regions
- """
- return [i.slug for i in self.regions]
-
-
-
var regions
-
-
Return a list regions available on digital ocean
-
e.g
-dg.regions
--> [, ,…]
-
Returns
-List : list of regions
-
-Source code
-
@property
-def regions(self):
- """Return a list regions available on digital ocean
-
- e.g
- dg.regions -> [<Region: nyc1 New York 1>, <Region: sgp1 Singapore 1>,...]
-
- Returns
- List : list of regions
- """
- return self.client.get_all_regions()
@property
-def sizes(self):
- """Return a list sizes available on digital ocean
-
- e.g
- dg.sizes -> [s-1vcpu-1gb, 512mb, s-1vcpu-2gb, 1gb, s-3vcpu-1gb,.....]
-
- Returns
- List : list of sizes
- """
- return self.client.get_all_sizes()
-
-
-
var sshkeys
-
-
Return list of sshkeys on digital ocean
-
e.g
-dg.sshkeys
--> [,
-,…]
-
Returns
-list : list of sshkeys
-
-Source code
-
@property
-def sshkeys(self):
- """
- Return list of sshkeys on digital ocean
-
- e.g
- dg.sshkeys -> [<SSHKey: 25882170 3bot_container_sandbox>,
- <SSHKey: 27130645 Geert-root>,...]
-
- Returns
- list : list of sshkeys
- """
-
- return self.client.get_all_sshkeys()
-
-
-
var token_
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
-
Methods
-
-
-def get_default_sshkey(self)
-
-
-
Return sshkey you have added to your Digital Ocean client
-
e.g
-dg.get_default_sshkey()
-->
-
-
Returns
-list : list of sshkeys
-
-Source code
-
def get_default_sshkey(self):
- """
- Return sshkey you have added to your Digital Ocean client
-
- e.g
- dg.get_default_sshkey() -> <SSHKey: 25589987 rafy@rafy-Inspiron-3576>
-
- Returns
- list : list of sshkeys
- """
- pubkeyonly = self.sshkey.public_key
- for item in self.sshkeys:
- if item.public_key.find(pubkeyonly) != -1:
- return item
- return None
-
-
-
-def get_image(self, name)
-
-
-
Return an image
-
e.g
-dg.get_image(name="CentOS")
-->
-
Args
-name (str): name of the
-required image
-Returns
-Image : list of images on digital ocean images and the images you have created
-
-Source code
-
def get_image(self, name):
- """Return an image
-
- e.g
- dg.get_image(name="CentOS") -> <Image: 31354013 CentOS 6.9 x32>
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images on digital ocean images and the images you have created
- """
- for item in self.account_images:
- if item.description:
- name_do1 = item.description.lower()
- else:
- name_do1 = ""
- name_do2 = item.distribution + " " + item.name
- print(f" - {name_do1}--{name_do2}")
- if name_do1.lower().find(name.lower()) != -1 or name_do2.lower().find(name.lower()) != -1:
- return item
- raise j.exceptions.Base("did not find image:%s" % name)
-
-
-
-def get_image_names(self, name='')
-
-
-
Return all the image
-or images with a specified name
-e.g
-dg.get_image_names()
--> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602',…]
-dg.get_image_names("centos") -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602']
-
Args
-name (str): name of the
-required image
-Returns
-Image : list of images
-
-Source code
-
def get_image_names(self, name=""):
- """ Return all the image or images with a specified name
- e.g
- dg.get_image_names() -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602',...]
- dg.get_image_names("centos") -> ['centos 6.9 x32 20180130', 'centos 6.9 x64 20180602']
-
- Args
- name (str): name of the required image
- Returns
- Image : list of images
- """
- res = []
- name = name.lower()
- for item in self.images:
- if item.description:
- name_do = item.description.lower()
- else:
- name_do = item.distribution + " " + item.name
- if name_do.find(name) != -1:
- res.append(name_do)
- return res
-
-
-
-def get_region(self, name)
-
-
-
Returns specific region
-
e.g
-dg.get_region(name = 'nyc1')
-->
-
Args
-name (str) : name of the required region
-Returns
-Region : the region with the name specified
-
-Source code
-
def get_region(self, name):
- """
- Returns specific region
-
- e.g
- dg.get_region(name = 'nyc1') -> <Region: nyc1 New York 1>
-
- Args
- name (str) : name of the required region
- Returns
- Region : the region with the name specified
- """
- for item in self.regions:
- if name == item.slug:
- return item
- if name == item.name:
- return item
- raise j.exceptions.Base("did not find region:%s" % name)
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class Droplet(Client):
- do_name = fields.String()
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def set_digital_ocean_name(self, name):
- """Set a name for your Droplet to be used on Digital Ocean
-
- e.g
- droplet.set_digital_ocean_name("test-name")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
-
- def get_digital_ocean_name(self):
- """Get a name for the Droplet which is used on digital ocean
-
- e.g
- droplet.get_digital_ocean_name() -> "test-name"
-
- Returns
- str: name for the droplet which is used on digital ocean
- """
- return self.do_name
-
- def deploy(
- self,
- sshkey=None,
- region="Amsterdam 3",
- image="ubuntu 18.04",
- size_slug="s-1vcpu-2gb",
- delete=True,
- project_name=None,
- ):
- """
- Deploy your Droplet to Digital Ocean
-
- Args
- sshkey (string): sshkey name used on digital ocean (if not set it will use the default one which already loaded)
- region (string): region name to deploy to
- image (string): Image name to be used
- size_slug (string): size of the droplet (s-1vcpu-2gb,s-6vcpu-16gb,gd-8vcpu-32gb)
- delete (bool): delete the droplet if it is already deployed on digital ocean
- project_name (string): project to add this droplet it. If not specified the default project will be used.
-
- """
- project = None
- if project_name:
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- if not project:
- raise j.exceptions.Input("could not find project with name:%s" % project_name)
-
- # Get ssh
- if not sshkey:
- sshkey_do = self.parent.get_default_sshkey()
-
- if not sshkey_do:
- # means we did not find the sshkey on digital ocean yet, need to create
- sshkey = self.parent.sshkey
- key = digitalocean.SSHKey(
- token=self.parent.projects.parent_instance.token_, name=sshkey.name, public_key=sshkey.public_key
- )
- key.create()
- sshkey_do = self.parent.get_default_sshkey()
- assert sshkey_do
- sshkey = sshkey_do.name
-
- if self.parent.droplets.check_droplet_exist_remote(self.do_name):
- dr0 = self.parent.droplets.get_droplet_exist_remote(self.do_name)
- if delete:
- dr0.destroy()
- else:
- sshcl = j.clients.sshclient.get(name="do_%s" % self.do_name, host=dr0.ip_address, sshkey=sshkey)
- return dr0, sshcl
-
- sshkey = self.parent.droplets.parent_instance.get_sshkey(sshkey)
- region = self.parent.droplets.parent_instance.get_region(region)
- imagedo = self.parent.droplets.parent_instance.get_image(image)
-
- img_slug_or_id = imagedo.slug if imagedo.slug else imagedo.id
-
- droplet = digitalocean.Droplet(
- token=self.parent.droplets.parent_instance.token_,
- name=self.do_name,
- region=region.slug,
- image=img_slug_or_id,
- size_slug=size_slug,
- ssh_keys=[sshkey],
- backups=False,
- )
- droplet.create()
-
- if project:
- project.assign_resources(["do:droplet:%s" % droplet.id])
-
- def delete_remote(self):
- """Delete Droplet from digital ocean
-
- e.g
- droplet.delete_remote()
-
- """
- droplet = self.parent.droplets.get_droplet_exist_remote(self.do_name)
- droplet.destroy()
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
Args
-sshkey (string): sshkey name used on digital ocean (if not set it will use the default one which already loaded)
-region (string): region name to deploy to
-image (string): Image name to be used
-size_slug (string): size of the droplet
-(s-1vcpu-2gb,s-6vcpu-16gb,gd-8vcpu-32gb)
-delete (bool): delete the droplet if it is already deployed on digital ocean
-project_name (string): project to add this droplet it. If not specified the default project will be used.
-
-Source code
-
def deploy(
- self,
- sshkey=None,
- region="Amsterdam 3",
- image="ubuntu 18.04",
- size_slug="s-1vcpu-2gb",
- delete=True,
- project_name=None,
-):
- """
- Deploy your Droplet to Digital Ocean
-
- Args
- sshkey (string): sshkey name used on digital ocean (if not set it will use the default one which already loaded)
- region (string): region name to deploy to
- image (string): Image name to be used
- size_slug (string): size of the droplet (s-1vcpu-2gb,s-6vcpu-16gb,gd-8vcpu-32gb)
- delete (bool): delete the droplet if it is already deployed on digital ocean
- project_name (string): project to add this droplet it. If not specified the default project will be used.
-
- """
- project = None
- if project_name:
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- if not project:
- raise j.exceptions.Input("could not find project with name:%s" % project_name)
-
- # Get ssh
- if not sshkey:
- sshkey_do = self.parent.get_default_sshkey()
-
- if not sshkey_do:
- # means we did not find the sshkey on digital ocean yet, need to create
- sshkey = self.parent.sshkey
- key = digitalocean.SSHKey(
- token=self.parent.projects.parent_instance.token_, name=sshkey.name, public_key=sshkey.public_key
- )
- key.create()
- sshkey_do = self.parent.get_default_sshkey()
- assert sshkey_do
- sshkey = sshkey_do.name
-
- if self.parent.droplets.check_droplet_exist_remote(self.do_name):
- dr0 = self.parent.droplets.get_droplet_exist_remote(self.do_name)
- if delete:
- dr0.destroy()
- else:
- sshcl = j.clients.sshclient.get(name="do_%s" % self.do_name, host=dr0.ip_address, sshkey=sshkey)
- return dr0, sshcl
-
- sshkey = self.parent.droplets.parent_instance.get_sshkey(sshkey)
- region = self.parent.droplets.parent_instance.get_region(region)
- imagedo = self.parent.droplets.parent_instance.get_image(image)
-
- img_slug_or_id = imagedo.slug if imagedo.slug else imagedo.id
-
- droplet = digitalocean.Droplet(
- token=self.parent.droplets.parent_instance.token_,
- name=self.do_name,
- region=region.slug,
- image=img_slug_or_id,
- size_slug=size_slug,
- ssh_keys=[sshkey],
- backups=False,
- )
- droplet.create()
-
- if project:
- project.assign_resources(["do:droplet:%s" % droplet.id])
-
-
-
-def get_digital_ocean_name(self)
-
-
-
Get a name for the Droplet which is used on digital ocean
Returns
-str: name for the droplet which is used on digital ocean
-
-Source code
-
def get_digital_ocean_name(self):
- """Get a name for the Droplet which is used on digital ocean
-
- e.g
- droplet.get_digital_ocean_name() -> "test-name"
-
- Returns
- str: name for the droplet which is used on digital ocean
- """
- return self.do_name
-
-
-
-def set_digital_ocean_name(self, name)
-
-
-
Set a name for your Droplet to be used on Digital Ocean
def set_digital_ocean_name(self, name):
- """Set a name for your Droplet to be used on Digital Ocean
-
- e.g
- droplet.set_digital_ocean_name("test-name")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
Stored factories are a custom type of Factory, which uses current configured store backend
-to store all instance configurations.
-
get a new stored factory given the type to create and store instances for.
-
Any factory can have a name, parent Base instance and a parent factory.
-
Once a stored factory is created, it tries to lazy-load all current configuration for given type_.
-
Args
-
-
type_ : Base
-
Base class type
-
name_ : str, optional
-
factory name. Defaults to None.
-
parent_instance_ : Base, optional
-
a parent Base instance. Defaults to None.
-
parent_factory_ : Factory, optional
-
a parent Factory. Defaults to None.
-
-
-Source code
-
class DropletFactory(StoredFactory):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def list_remote(self, project_name=None):
- """
- List all remote droplet or list droplets for a project if it is specified
-
- e.g
- dg.droplets.list_remote() -> list of droplets
- dg.droplets.list_remote("codescalers") -> list of droplets on codescalers project
-
- Args:
- project_name (str) : name of project on digital ocean (optional)
-
- Returns
- list (Droplet) : list of droplets on digital ocean
-
-
- """
- if project_name:
- project = self.parent_instance.projects.get_project_exist_remote(project_name)
- return project.list_droplets()
-
- return self.parent_instance.client.get_all_droplets()
-
- def check_droplet_exist_remote(self, name):
- """
- Check droplet exists on digital ocean
-
- e.g
- dg.droplets.check_droplet_exist_remote("3git") -> True
- dg.droplets.check_droplet_exist_remote("sdfgdfed") -> False
-
- Args:
- name (str) : name of droplet
-
- Returns
- bool : True if the droplet exist or False if the droplet does not exist
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return True
- return False
-
- def get_droplet_exist_remote(self, name):
- """
- Get Droplet exists from Digital Ocean
-
- e.g
- dg.droplets.get_droplet_exist_remote("3git")
-
- Args:
- name (str) : name of droplet
-
- Returns
- droplet : droplet with the name specified
-
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return droplet
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
-
- def shutdown_all(self, project_name=None):
- """
- Shutdown all the droplets or droplets in specific project
-
- e.g
- dg.droplets.shutdown_all("codescalers")
- dg.droplets.shutdown_all()
-
- Args:
- name (str) : name of the project
-
- """
- for droplet in self.list_remote(project_name):
- droplet.shutdown()
-
- def delete_all(self, ignore=None, interactive=True, project_name=None):
- """
- Delete all the droplets or delete all the droplets in specific project
-
- e.g
- dg.droplets.delete_all(project_name = "codescalers")
- dg.droplets.delete_all()
-
- Args:
- project_name (str) : name of the project
- ignore (list): list of ignored droplets to prevent their deletion
- interactive (bool): if True the deletion will be interactive and
- confirm if you want to delete but if False it
- will delete directly
- """
- if not ignore:
- ignore = []
-
- def test(ignore, name):
- if name.startswith("TF-"):
- return False
- for item in ignore:
- if name.lower().find(item.lower()) != -1:
- return False
- return True
-
- todo = []
- for droplet in self.list_remote(project_name):
- if test(ignore, droplet.name):
- todo.append(droplet)
- if todo != []:
- todotxt = ",".join([i.name for i in todo])
- if not interactive or j.tools.console.ask_yes_no("ok to delete:%s" % todotxt):
- for droplet in todo:
- droplet.destroy()
bool : True if the droplet exist or False if the droplet does not exist
-
-
-Source code
-
def check_droplet_exist_remote(self, name):
- """
- Check droplet exists on digital ocean
-
- e.g
- dg.droplets.check_droplet_exist_remote("3git") -> True
- dg.droplets.check_droplet_exist_remote("sdfgdfed") -> False
-
- Args:
- name (str) : name of droplet
-
- Returns
- bool : True if the droplet exist or False if the droplet does not exist
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return True
- return False
list of ignored droplets to prevent their deletion
-
interactive : bool
-
if True the deletion will be interactive and
-confirm if you want to delete but if False it
-will delete directly
-
-
-Source code
-
def delete_all(self, ignore=None, interactive=True, project_name=None):
- """
- Delete all the droplets or delete all the droplets in specific project
-
- e.g
- dg.droplets.delete_all(project_name = "codescalers")
- dg.droplets.delete_all()
-
- Args:
- project_name (str) : name of the project
- ignore (list): list of ignored droplets to prevent their deletion
- interactive (bool): if True the deletion will be interactive and
- confirm if you want to delete but if False it
- will delete directly
- """
- if not ignore:
- ignore = []
-
- def test(ignore, name):
- if name.startswith("TF-"):
- return False
- for item in ignore:
- if name.lower().find(item.lower()) != -1:
- return False
- return True
-
- todo = []
- for droplet in self.list_remote(project_name):
- if test(ignore, droplet.name):
- todo.append(droplet)
- if todo != []:
- todotxt = ",".join([i.name for i in todo])
- if not interactive or j.tools.console.ask_yes_no("ok to delete:%s" % todotxt):
- for droplet in todo:
- droplet.destroy()
-
-
-
-def get_droplet_exist_remote(self, name)
-
-
-
Get Droplet exists from Digital Ocean
-
e.g
-dg.droplets.get_droplet_exist_remote("3git")
-
Args
-
-
name (str) : name of droplet
-
Returns
-
droplet : droplet with the name specified
-
-
-Source code
-
def get_droplet_exist_remote(self, name):
- """
- Get Droplet exists from Digital Ocean
-
- e.g
- dg.droplets.get_droplet_exist_remote("3git")
-
- Args:
- name (str) : name of droplet
-
- Returns
- droplet : droplet with the name specified
-
- """
- for droplet in self.list_remote():
- if droplet.name.lower() == name.lower():
- return droplet
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
-
-
-
-def list_remote(self, project_name=None)
-
-
-
List all remote droplet or list droplets for a project if it is specified
-
e.g
-dg.droplets.list_remote()
--> list of droplets
-dg.droplets.list_remote("codescalers")
--> list of droplets on codescalers project
-
Args
-
-
project_name (str) : name of project on digital ocean (optional)
-
Returns
-
list (Droplet) : list of droplets on digital ocean
-
-
-Source code
-
def list_remote(self, project_name=None):
- """
- List all remote droplet or list droplets for a project if it is specified
-
- e.g
- dg.droplets.list_remote() -> list of droplets
- dg.droplets.list_remote("codescalers") -> list of droplets on codescalers project
-
- Args:
- project_name (str) : name of project on digital ocean (optional)
-
- Returns
- list (Droplet) : list of droplets on digital ocean
-
-
- """
- if project_name:
- project = self.parent_instance.projects.get_project_exist_remote(project_name)
- return project.list_droplets()
-
- return self.parent_instance.client.get_all_droplets()
-
-
-
-def shutdown_all(self, project_name=None)
-
-
-
Shutdown all the droplets or droplets in specific project
-
def shutdown_all(self, project_name=None):
- """
- Shutdown all the droplets or droplets in specific project
-
- e.g
- dg.droplets.shutdown_all("codescalers")
- dg.droplets.shutdown_all()
-
- Args:
- name (str) : name of the project
-
- """
- for droplet in self.list_remote(project_name):
- droplet.shutdown()
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class Project(Client):
- do_name = fields.String()
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def set_digital_ocean_name(self, name):
- """Set a name for your project to be used on Digital Ocean
- e.g
- project.set_digital_ocean_name("test project DO client")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
-
- def get_digital_ocean_name(self):
- """Get a name for the project which is used on digital ocean
- e.g
- project.get_digital_ocean_name() -> "test project DO client"
-
- Returns:
- str: name for the project which is used on digital ocean
- """
- return self.do_name
-
- def deploy(self, purpose, description="", environment="", is_default=False):
- """Create a digital ocean project
- e.g
- project.deploy(purpose="testing digital ocean client") -> project
- Args:
- purpose(str): purpose of the project (not optional)
- description(str): description of the project, defaults to ""
- environment(str): environment of project's resources, defaults to ""
- is_default(bool): make this the default project for your user
-
- Returns:
- project: The project object that has been created
- """
-
- if self.parent.projects.check_project_exist_remote(self.do_name):
- raise j.exceptions.Value("A project with the same name already exists")
-
- project = ProjectManagement(
- token=self.parent.projects.parent_instance.token_,
- name=self.do_name,
- purpose=purpose,
- description=description,
- environment=environment,
- is_default=is_default,
- )
- project.create()
-
- if is_default:
- project.update(is_default=True)
-
- return project
-
- def delete_remote(self):
- """Delete the project from Digital Ocean (A project can't be deleted unless it has no resources.)
-
- e.g
- project.delete_remote()
- """
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- project.delete()
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
-
Methods
-
-
-def delete_remote(self)
-
-
-
Delete the project from Digital Ocean (A project can't be deleted unless it has no resources.)
-
e.g
-project.delete_remote()
-
-Source code
-
def delete_remote(self):
- """Delete the project from Digital Ocean (A project can't be deleted unless it has no resources.)
-
- e.g
- project.delete_remote()
- """
- project = self.parent.projects.get_project_exist_remote(self.do_name)
- project.delete()
Create a digital ocean project
-e.g
-project.deploy(purpose="testing digital ocean client")
--> project
-
Args
-
purpose(str): purpose of the project (not optional)
-description(str): description of the project, defaults to ""
-environment(str): environment of project's resources, defaults to ""
-is_default(bool): make this the default project for your user
-
Returns
-
-
project
-
The project object that has been created
-
-
-Source code
-
def deploy(self, purpose, description="", environment="", is_default=False):
- """Create a digital ocean project
- e.g
- project.deploy(purpose="testing digital ocean client") -> project
- Args:
- purpose(str): purpose of the project (not optional)
- description(str): description of the project, defaults to ""
- environment(str): environment of project's resources, defaults to ""
- is_default(bool): make this the default project for your user
-
- Returns:
- project: The project object that has been created
- """
-
- if self.parent.projects.check_project_exist_remote(self.do_name):
- raise j.exceptions.Value("A project with the same name already exists")
-
- project = ProjectManagement(
- token=self.parent.projects.parent_instance.token_,
- name=self.do_name,
- purpose=purpose,
- description=description,
- environment=environment,
- is_default=is_default,
- )
- project.create()
-
- if is_default:
- project.update(is_default=True)
-
- return project
-
-
-
-def get_digital_ocean_name(self)
-
-
-
Get a name for the project which is used on digital ocean
-e.g
-project.get_digital_ocean_name()
-->
-"test project DO client"
-
Returns
-
-
str
-
name for the project which is used on digital ocean
-
-
-Source code
-
def get_digital_ocean_name(self):
- """Get a name for the project which is used on digital ocean
- e.g
- project.get_digital_ocean_name() -> "test project DO client"
-
- Returns:
- str: name for the project which is used on digital ocean
- """
- return self.do_name
-
-
-
-def set_digital_ocean_name(self, name)
-
-
-
Set a name for your project to be used on Digital Ocean
-e.g
-project.set_digital_ocean_name("test project DO client")
-
Args
-
-
name : str
-
name to be used on digital ocean
-
-
-Source code
-
def set_digital_ocean_name(self, name):
- """Set a name for your project to be used on Digital Ocean
- e.g
- project.set_digital_ocean_name("test project DO client")
-
- Args:
- name (str): name to be used on digital ocean
- """
- self.do_name = name
Stored factories are a custom type of Factory, which uses current configured store backend
-to store all instance configurations.
-
get a new stored factory given the type to create and store instances for.
-
Any factory can have a name, parent Base instance and a parent factory.
-
Once a stored factory is created, it tries to lazy-load all current configuration for given type_.
-
Args
-
-
type_ : Base
-
Base class type
-
name_ : str, optional
-
factory name. Defaults to None.
-
parent_instance_ : Base, optional
-
a parent Base instance. Defaults to None.
-
parent_factory_ : Factory, optional
-
a parent Factory. Defaults to None.
-
-
-Source code
-
class ProjectFactory(StoredFactory):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- def list_remote(self):
- """
- Returns list of projects on Digital Ocean
-
- e.g
- dg.projects.list_remote() -> list of projects
-
- Returns
- list(projects): list of projects on digital ocean
-
- """
- return ProjectManagement.list(self.parent_instance.client)
-
- def check_project_exist_remote(self, name):
- """
- Check a project with specific name exits on Digital Ocean
-
- e.g
- dg.projects.check_project_exist_remote("codescalers") -> True
- dg.projects.check_project_exist_remote("dsrfjsdfjl") -> False
-
- Args
- name (str): name of the project
-
- Returns
- bool : True if the project exits and False if the project does not exist on digital ocean
- """
- for project in self.list_remote():
- if project.name == name:
- return True
- return False
-
- def get_project_exist_remote(self, name):
- """
- Get a project with specifc name from Digital Ocean.
-
- e.g
- dg.projects.get_project_exist_remote("codescalers") -> project
-
- Args
- name (str): name of the project
-
- Returns
- Project : a project from digital ocean with the name specified
- """
- for project in self.list_remote():
- if project.name == name:
- return project
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
Returns
-bool : True if the project exits and False if the project does not exist on digital ocean
-
-Source code
-
def check_project_exist_remote(self, name):
- """
- Check a project with specific name exits on Digital Ocean
-
- e.g
- dg.projects.check_project_exist_remote("codescalers") -> True
- dg.projects.check_project_exist_remote("dsrfjsdfjl") -> False
-
- Args
- name (str): name of the project
-
- Returns
- bool : True if the project exits and False if the project does not exist on digital ocean
- """
- for project in self.list_remote():
- if project.name == name:
- return True
- return False
-
-
-
-def get_project_exist_remote(self, name)
-
-
-
Get a project with specifc name from
-Digital Ocean.
Returns
-Project : a project from digital ocean with the name specified
-
-Source code
-
def get_project_exist_remote(self, name):
- """
- Get a project with specifc name from Digital Ocean.
-
- e.g
- dg.projects.get_project_exist_remote("codescalers") -> project
-
- Args
- name (str): name of the project
-
- Returns
- Project : a project from digital ocean with the name specified
- """
- for project in self.list_remote():
- if project.name == name:
- return project
- raise j.exceptions.Input("could not find project with name:%s on you Digital Ocean account" % name)
-
-
-
-def list_remote(self)
-
-
-
Returns list of projects on Digital Ocean
-
e.g
-dg.projects.list_remote()
--> list of projects
-
Returns
-list(projects): list of projects on digital ocean
-
-Source code
-
def list_remote(self):
- """
- Returns list of projects on Digital Ocean
-
- e.g
- dg.projects.list_remote() -> list of projects
-
- Returns
- list(projects): list of projects on digital ocean
-
- """
- return ProjectManagement.list(self.parent_instance.client)
from digitalocean import Droplet
-from digitalocean.baseapi import BaseAPI, Error, GET, POST, DELETE, PUT
-
-
-class ProjectManagement(BaseAPI):
- """Project management
-
- Attributes accepted at creation time:
-
- Args:
- name (str): project name
- description (str): project size
- purpose (str): purpose of the project
- environemnt (str): environment of the project's resources
-
- Attributes returned by API:
- * id (int): project id
- * owner_uuid (str): uuid of the project owner
- * owner_id (str): id of the project owner
- * name (str): project name
- * description (str): project description
- * purpose (str): project purpose
- * environment (str): environment of the project's resources
- * is_default (bool): If true, all resources will be added to this project if no project is specified.
- * created_at (str): creation date in format u'2014-11-06T10:42:09Z'
- * updated_at (str): update date in format u'2014-11-06T10:42:09Z'
-
- """
-
- def __init__(self, *args, **kwargs):
- # Defining default values
- self.id = None
- self.name = None
- self.owner_uuid = None
- self.owner_id = None
- self.description = None
- self.purpose = None
- self.environment = None
- self.is_default = False
- self.updated_at = None
- self.created_at = None
-
- # This will load also the values passed
- super(ProjectManagement, self).__init__(*args, **kwargs)
-
- @classmethod
- def get_object(cls, api_token, project_id):
- """Class method that will return a Project object by ID.
-
- Args:
- api_token (str): token
- project_id (int): project id
- """
- project = cls(token=api_token, id=project_id)
- project.load()
- return project
-
- @classmethod
- def list(cls, client):
-
- data = client.get_data("projects")
-
- projects = list()
- for jsoned in data["projects"]:
- project = cls(**jsoned)
- project.token = client.token
-
- projects.append(project)
-
- return projects
-
- def load(self):
- """
- Fetch data about project - use this instead of get_data()
- """
- projects = self.get_data("projects/%s" % self.id)
- project = projects["project"]
-
- for attr in project.keys():
- setattr(self, attr, project[attr])
-
- return self
-
- def _update_data(self, project):
- self.id = project["id"]
- self.owner_uuid = project["owner_uuid"]
- self.owner_id = project["owner_id"]
- self.name = project["name"]
- self.description = project["description"]
- self.purpose = project["purpose"]
- self.environment = project["environment"]
- self.is_default = project["is_default"]
- self.created_at = project["created_at"]
- self.updated_at = project["updated_at"]
-
- def create(self, *args, **kwargs):
- """
- Create the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- }
-
- data = self.get_data("projects", type=POST, params=data)
- self._update_data(data["project"])
-
- def update(self, *args, **kwargs):
- """
- Update the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- "is_default": self.is_default,
- }
-
- data = self.get_data("projects/%s" % self.id, type=PUT, params=data)
- self._update_data(data["project"])
-
- def delete(self):
- """
- Delete the project.
- To be deleted, a project must not have any resources assigned to it. Any existing resources must first be reassigned or destroyed.
- """
- self.get_data("projects/%s" % self.id, type=DELETE)
-
- def list_resources(self):
- """
- List all resources in the project
- """
- return self.get_data("projects/%s/resources" % self.id)["resources"]
-
- def list_droplets(self):
- """
- List all droplets in the project
- """
- resources = self.list_resources()
- droplets = []
- for resource in resources:
- if not resource["urn"].startswith("do:droplet:"):
- continue
- droplet_id = resource["urn"].replace("do:droplet:", "")
- droplet = Droplet.get_object(api_token=self.token, droplet_id=droplet_id)
- droplets.append(droplet)
-
- return droplets
-
- def assign_resources(self, resources):
- """Assign resources to the project.
-
- :param resources: A list of uniform resource names (URNs) to be added to a project.
- :type resources: [str]
- """
- self.get_data("projects/%s/resources" % self.id, type=POST, params={"resources": resources})
-
- def __str__(self):
- return "<Project: %s %s>" % (self.id, self.name)
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class ProjectManagement
-(*args, **kwargs)
-
-
-
Project management
-
Attributes accepted at creation time:
-
Args
-
-
name : str
-
project name
-
description : str
-
project size
-
purpose : str
-
purpose of the project
-
environemnt : str
-
environment of the project's resources
-
-
Attributes returned by API:
-* id (int): project id
-* owner_uuid (str): uuid of the project owner
-* owner_id (str): id of the project owner
-* name (str): project name
-* description (str): project description
-* purpose (str): project purpose
-* environment (str): environment of the project's resources
-* is_default (bool): If true, all resources will be added to this project if no project is specified.
-* created_at (str): creation date in format u'2014-11-06T10:42:09Z'
-* updated_at (str): update date in format u'2014-11-06T10:42:09Z'
-
-Source code
-
class ProjectManagement(BaseAPI):
- """Project management
-
- Attributes accepted at creation time:
-
- Args:
- name (str): project name
- description (str): project size
- purpose (str): purpose of the project
- environemnt (str): environment of the project's resources
-
- Attributes returned by API:
- * id (int): project id
- * owner_uuid (str): uuid of the project owner
- * owner_id (str): id of the project owner
- * name (str): project name
- * description (str): project description
- * purpose (str): project purpose
- * environment (str): environment of the project's resources
- * is_default (bool): If true, all resources will be added to this project if no project is specified.
- * created_at (str): creation date in format u'2014-11-06T10:42:09Z'
- * updated_at (str): update date in format u'2014-11-06T10:42:09Z'
-
- """
-
- def __init__(self, *args, **kwargs):
- # Defining default values
- self.id = None
- self.name = None
- self.owner_uuid = None
- self.owner_id = None
- self.description = None
- self.purpose = None
- self.environment = None
- self.is_default = False
- self.updated_at = None
- self.created_at = None
-
- # This will load also the values passed
- super(ProjectManagement, self).__init__(*args, **kwargs)
-
- @classmethod
- def get_object(cls, api_token, project_id):
- """Class method that will return a Project object by ID.
-
- Args:
- api_token (str): token
- project_id (int): project id
- """
- project = cls(token=api_token, id=project_id)
- project.load()
- return project
-
- @classmethod
- def list(cls, client):
-
- data = client.get_data("projects")
-
- projects = list()
- for jsoned in data["projects"]:
- project = cls(**jsoned)
- project.token = client.token
-
- projects.append(project)
-
- return projects
-
- def load(self):
- """
- Fetch data about project - use this instead of get_data()
- """
- projects = self.get_data("projects/%s" % self.id)
- project = projects["project"]
-
- for attr in project.keys():
- setattr(self, attr, project[attr])
-
- return self
-
- def _update_data(self, project):
- self.id = project["id"]
- self.owner_uuid = project["owner_uuid"]
- self.owner_id = project["owner_id"]
- self.name = project["name"]
- self.description = project["description"]
- self.purpose = project["purpose"]
- self.environment = project["environment"]
- self.is_default = project["is_default"]
- self.created_at = project["created_at"]
- self.updated_at = project["updated_at"]
-
- def create(self, *args, **kwargs):
- """
- Create the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- }
-
- data = self.get_data("projects", type=POST, params=data)
- self._update_data(data["project"])
-
- def update(self, *args, **kwargs):
- """
- Update the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- "is_default": self.is_default,
- }
-
- data = self.get_data("projects/%s" % self.id, type=PUT, params=data)
- self._update_data(data["project"])
-
- def delete(self):
- """
- Delete the project.
- To be deleted, a project must not have any resources assigned to it. Any existing resources must first be reassigned or destroyed.
- """
- self.get_data("projects/%s" % self.id, type=DELETE)
-
- def list_resources(self):
- """
- List all resources in the project
- """
- return self.get_data("projects/%s/resources" % self.id)["resources"]
-
- def list_droplets(self):
- """
- List all droplets in the project
- """
- resources = self.list_resources()
- droplets = []
- for resource in resources:
- if not resource["urn"].startswith("do:droplet:"):
- continue
- droplet_id = resource["urn"].replace("do:droplet:", "")
- droplet = Droplet.get_object(api_token=self.token, droplet_id=droplet_id)
- droplets.append(droplet)
-
- return droplets
-
- def assign_resources(self, resources):
- """Assign resources to the project.
-
- :param resources: A list of uniform resource names (URNs) to be added to a project.
- :type resources: [str]
- """
- self.get_data("projects/%s/resources" % self.id, type=POST, params={"resources": resources})
-
- def __str__(self):
- return "<Project: %s %s>" % (self.id, self.name)
-
-
Ancestors
-
-
digitalocean.BaseAPI
-
-
Static methods
-
-
-def get_object(api_token, project_id)
-
-
-
Class method that will return a Project object by ID.
-
Args
-
-
api_token : str
-
token
-
project_id : int
-
project id
-
-
-Source code
-
@classmethod
-def get_object(cls, api_token, project_id):
- """Class method that will return a Project object by ID.
-
- Args:
- api_token (str): token
- project_id (int): project id
- """
- project = cls(token=api_token, id=project_id)
- project.load()
- return project
:param resources: A list of uniform resource names (URNs) to be added to a project.
-:type resources: [str]
-
-Source code
-
def assign_resources(self, resources):
- """Assign resources to the project.
-
- :param resources: A list of uniform resource names (URNs) to be added to a project.
- :type resources: [str]
- """
- self.get_data("projects/%s/resources" % self.id, type=POST, params={"resources": resources})
-
-
-
-def create(self, *args, **kwargs)
-
-
-
Create the project with object properties.
-
Note: Every argument and parameter given to this method will be
-assigned to the object.
-
-Source code
-
def create(self, *args, **kwargs):
- """
- Create the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- }
-
- data = self.get_data("projects", type=POST, params=data)
- self._update_data(data["project"])
-
-
-
-def delete(self)
-
-
-
Delete the project.
-To be deleted, a project must not have any resources assigned to it. Any existing resources must first be reassigned or destroyed.
-
-Source code
-
def delete(self):
- """
- Delete the project.
- To be deleted, a project must not have any resources assigned to it. Any existing resources must first be reassigned or destroyed.
- """
- self.get_data("projects/%s" % self.id, type=DELETE)
-
-
-
-def list_droplets(self)
-
-
-
List all droplets in the project
-
-Source code
-
def list_droplets(self):
- """
- List all droplets in the project
- """
- resources = self.list_resources()
- droplets = []
- for resource in resources:
- if not resource["urn"].startswith("do:droplet:"):
- continue
- droplet_id = resource["urn"].replace("do:droplet:", "")
- droplet = Droplet.get_object(api_token=self.token, droplet_id=droplet_id)
- droplets.append(droplet)
-
- return droplets
-
-
-
-def list_resources(self)
-
-
-
List all resources in the project
-
-Source code
-
def list_resources(self):
- """
- List all resources in the project
- """
- return self.get_data("projects/%s/resources" % self.id)["resources"]
-
-
-
-def load(self)
-
-
-
Fetch data about project - use this instead of get_data()
-
-Source code
-
def load(self):
- """
- Fetch data about project - use this instead of get_data()
- """
- projects = self.get_data("projects/%s" % self.id)
- project = projects["project"]
-
- for attr in project.keys():
- setattr(self, attr, project[attr])
-
- return self
-
-
-
-def update(self, *args, **kwargs)
-
-
-
Update the project with object properties.
-
Note: Every argument and parameter given to this method will be
-assigned to the object.
-
-Source code
-
def update(self, *args, **kwargs):
- """
- Update the project with object properties.
-
- Note: Every argument and parameter given to this method will be
- assigned to the object.
- """
- for attr in kwargs.keys():
- setattr(self, attr, kwargs[attr])
-
- data = {
- "name": self.name,
- "description": self.description,
- "purpose": self.purpose,
- "environment": self.environment,
- "is_default": self.is_default,
- }
-
- data = self.get_data("projects/%s" % self.id, type=PUT, params=data)
- self._update_data(data["project"])
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/clients/gdrive/gdrive.html b/docs/api/jumpscale/clients/gdrive/gdrive.html
deleted file mode 100644
index d5f84cac2..000000000
--- a/docs/api/jumpscale/clients/gdrive/gdrive.html
+++ /dev/null
@@ -1,308 +0,0 @@
-
-
-
-
-
-
-jumpscale.clients.gdrive.gdrive API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
@property
-def credentials(self):
- if not self.__credentials:
- self.__credentials = service_account.Credentials.from_service_account_file(
- self.credfile, scopes=SCOPES
- )
- return self.__credentials
-
-
-
var credfile
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var files
-
-
-
-Source code
-
@property
-def files(self):
- if not self.__files:
- drive = self.get_service("drive", DRIVE_BUILD_VERSION)
- self.__files = drive.files()
- return self.__files
-
-
-
-
Methods
-
-
-def export_pdf(self, file_id, export_path)
-
-
-
-
-Source code
-
def export_pdf(self, file_id, export_path):
- response = self.files.export_media(fileId=file_id, mimeType="application/pdf").execute()
- with open(export_path, "wb") as expr:
- expr.write(response)
class ActorProxy:
- def __init__(self, actor_name, actor_info, client):
- """ActorProxy to remote actor on the server side
-
- Arguments:
- actor_name {str} -- [description]
- actor_info {dict} -- actor information dict e.g { method_name: { args: [], 'doc':...} }
- gedis_client {GedisClient} -- gedis client reference
- """
- self.actor_name = actor_name
- self.actor_info = actor_info
- self.client = client
-
- def __dir__(self):
- """Delegate the available functions on the ActorProxy to `actor_info` keys
-
- Returns:
- list -- methods available on the ActorProxy
- """
- return list(self.actor_info["methods"].keys())
-
- def __getattr__(self, method):
- """Return a function representing the remote function on the actual actor
-
- Arguments:
- attr {str} -- method name
-
- Returns:
- function -- function waiting on the arguments
- """
-
- def function(*args, **kwargs):
- return self.client.execute(self.actor_name, method, *args, **kwargs)
-
- func = partial(function)
- func.__doc__ = self.actor_info["methods"][method]["doc"]
- return func
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var hostname
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var name
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var port
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var raise_on_error
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var redis_client
-
-
-
-Source code
-
@property
-def redis_client(self):
- if self._redisclient is None:
- self._redisclient = j.clients.redis.get(name=f"gedis_{self.name}", hostname=self.hostname, port=self.port)
- return self._redisclient
actor_name {str} – actor name
-actor_method {str} – actor method
-Keyword Arguments:
-die {bool} –
-flag to raise an error when request fails (default: {False})
def export_module_as():
-
- from jumpscale.core.base import StoredFactory
-
- from .gedis import GedisClient
-
- return StoredFactory(GedisClient)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/clients/github/base.html b/docs/api/jumpscale/clients/github/base.html
deleted file mode 100644
index a26cafd8e..000000000
--- a/docs/api/jumpscale/clients/github/base.html
+++ /dev/null
@@ -1,234 +0,0 @@
-
-
-
-
-
-
-jumpscale.clients.github.base API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.clients.github.base
-
-
-
-Source code
-
from jumpscale.clients.base import Client
-from jumpscale.core.base import Base, fields
-from jumpscale.loader import j
-
-replacelabels = {
- "bug": "type_bug",
- "duplicate": "process_duplicate",
- "enhancement": "type_feature",
- "help wanted": "state_question",
- "invalid": "state_question",
- "question": "state_question",
- "wontfix": "process_wontfix",
- "completed": "state_verification",
- "in progress": "state_inprogress",
- "ready": "state_verification",
- "story": "type_story",
- "urgent": "priority_urgent",
- "type_bug": "type_unknown",
- "type_story": "type_unknown",
-}
-
-
-class base(Base):
- def __init__(self):
- super().__init__()
-
- @property
- def body_without_tags(self):
- # remove the tag lines from the body
- out = ""
- if self.body is None:
- return ""
- for line in self.body.split("\n"):
- if line.startswith("##") and not line.startswith("###"):
- continue
- out += "%s\n" % line
-
- out = out.rstrip() + "\n"
- return out
-
- # @tags.setter
- # def tags(self, ddict):
- # if isinstance(ddict,dict) is False:
- # raise Exception("Tags need to be dict as input for setter, now:%s" % ddict)
-
- # keys = sorted(ddict.keys())
-
- # out = self.body_without_tags + "\n"
- # for key, val in ddict.items():
- # out += ".. %s:%s\n" % (key, val)
-
- # self.body = out
- # return self.tags
-
- def __str__(self):
- return str(self._ddict)
-
- __repr__ = __str__
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class base
-
-
-
A simple attribute-based namespace.
-
SimpleNamespace(**kwargs)
-
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class base(Base):
- def __init__(self):
- super().__init__()
-
- @property
- def body_without_tags(self):
- # remove the tag lines from the body
- out = ""
- if self.body is None:
- return ""
- for line in self.body.split("\n"):
- if line.startswith("##") and not line.startswith("###"):
- continue
- out += "%s\n" % line
-
- out = out.rstrip() + "\n"
- return out
-
- # @tags.setter
- # def tags(self, ddict):
- # if isinstance(ddict,dict) is False:
- # raise Exception("Tags need to be dict as input for setter, now:%s" % ddict)
-
- # keys = sorted(ddict.keys())
-
- # out = self.body_without_tags + "\n"
- # for key, val in ddict.items():
- # out += ".. %s:%s\n" % (key, val)
-
- # self.body = out
- # return self.tags
-
- def __str__(self):
- return str(self._ddict)
-
- __repr__ = __str__
@property
-def body_without_tags(self):
- # remove the tag lines from the body
- out = ""
- if self.body is None:
- return ""
- for line in self.body.split("\n"):
- if line.startswith("##") and not line.startswith("###"):
- continue
- out += "%s\n" % line
-
- out = out.rstrip() + "\n"
- return out
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var github_client
-
-
-
-Source code
-
@property
-def github_client(self):
- if not self.__client:
- if self.accesstoken:
- self.__client = Github(self.accesstoken)
- else:
- self.__client = Github(login_or_token=self.username, password=self.password)
- return self.__client
-
-
-
var password
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var username
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
def get_repos(self):
- l = []
- for r in self.github_client.get_user().get_repos():
- l.append(GithubRepo(self.__client,r.full_name))
- return l
-
-
-
-def get_userdata(self)
-
-
-
-
-Source code
-
def get_userdata(self):
- u = self.github_client.get_user()
- el = []
- for e in u.get_emails():
- el.append(e)
- return {"name": u.name, "emails": el, "id": u.id, "avatar_url": u.avatar_url}
@property
-def comments(self):
- if self._comments is not None:
- return self._comments
-
- with self._lock:
- if self._comments is None:
- self._log_debug("Loading comments for issue: %s" % self.number)
- self._comments = []
- for comment in self.api.get_comments():
- obj = {}
- user = self.repo.client.getUserLogin(githubObj=comment.user)
- obj["user"] = user
- obj["url"] = comment.url
- obj["id"] = comment.id
- obj["body"] = comment.body
- obj["user_id"] = comment.user.id
- # obj["time"] = j.data.time.any2HRDateTime([comment.last_modified, comment.created_at])
- self._comments.append(obj)
- return self._comments
-
-
-
var ddict
-
-
-
-Source code
-
@property
-def ddict(self):
- if self._ddict == {}:
- # no dict yet, fetch from github
- self.load()
- # we lazy load the comments. so it's only loaded when accesses
- self._ddict["comments"] = self.comments
- return self._ddict
@property
-def todo(self):
- if "_todo" not in self.__dict__:
- todo = []
- if self.body is not None:
- for line in self.body.split("\n"):
- if line.startswith("!! "):
- todo.append(line.strip().strip("!! "))
- for comment in self.comments:
- for line in comment["body"].split("\n"):
- if line.startswith("!! "):
- todo.append(line.strip().strip("!! "))
- self._todo = todo
- return self._todo
-
-
-
var type
-
-
-
-Source code
-
@property
-def type(self):
- items = []
- for label in self.labels:
- if label.startswith("type"):
- items.append(label)
- if len(items) == 1:
- return items[0].partition("_")[-1]
-
- return ""
import threading
-import copy
-import base64
-from .issue import Issue
-
-from .base import replacelabels
-from jumpscale.clients.base import Client
-from jumpscale.core.base import Base, fields
-from jumpscale.loader import j
-
-# import collections
-import urllib
-from .milestone import RepoMilestone
-from github.GithubException import UnknownObjectException
-
-
-class GithubRepo:
- TYPES = ["story", "ticket", "task", "bug", "feature", "question", "monitor", "unknown"]
- PRIORITIES = ["critical", "urgent", "normal", "minor"]
-
- STATES = ["new", "accepted", "question", "inprogress", "verification", "closed"]
-
- def __init__(self, client, fullname):
- self.client = client
- self.fullname = fullname
- self._repoclient = None
- self._labels = None
- self._issues = None
- self._lock = threading.RLock()
- self._milestones = None
-
- def _log_info(self, s):
- pass
-
- @property
- def api(self):
- if self._repoclient is None:
- self._repoclient = self.client.get_repo(self.fullname)
- return self._repoclient
-
- @property
- def name(self):
- return self.fullname.split("/", 1)[-1]
-
- @property
- def type(self):
- if self.name in ["home"]:
- return "home"
- elif self.name.startswith("proj"):
- return "proj"
- elif self.name.startswith("org_"):
- return "org"
- elif self.name.startswith("www"):
- return "www"
- elif self.name.startswith("doc"):
- return "doc"
- elif self.name.startswith("cockpit"):
- return "cockpit"
- else:
- return "code"
-
- @property
- def labelnames(self):
- return [item.name for item in self.labels]
-
- @property
- def labels(self):
- with self._lock:
- if self._labels is None:
- self._labels = [item for item in self.api.get_labels()]
-
- return self._labels
-
- @property
- def stories(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("story")
-
- @property
- def tasks(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("task")
-
- def labelsSet(self, labels2set, ignoreDelete=["p_"], delete=True):
- """
- @param ignore all labels starting with ignore will not be deleted
- """
-
- for item in labels2set:
- if not isinstance(item, str):
- raise Exception("Labels to set need to be in string format, found:%s" % labels2set)
-
- # walk over github existing labels
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- name = item.name.lower()
- if name not in labels2set:
- # label in repo does not correspond to label we need
- if name in replacelabels:
- nameNew = replacelabels[item.name.lower()]
- if nameNew not in self.labelnames:
- color = self.get_color(name)
- self._log_info(
- "change label in repo: %s oldlabel:'%s' to:'%s' color:%s"
- % (self.fullname, item.name, nameNew, color)
- )
- item.edit(nameNew, color)
- self._labels = None
- else:
- # no replacement
- name = "type_unknown"
- color = self.get_color(name)
- try:
- item.edit(name, color)
- except BaseException:
- item.delete()
- self._labels = None
-
- # walk over new labels we need to set
- for name in labels2set:
- if name not in self.labelnames:
- # does not exist yet in repo
- color = self.get_color(name)
- self._log_info("create label: %s %s %s" % (self.fullname, name, color))
- self.api.create_label(name, color)
- self._labels = None
-
- name = ""
-
- if delete:
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- if item.name not in labels2set:
- self._log_info("delete label: %s %s" % (self.fullname, item.name))
- ignoreDeleteDo = False
- for filteritem in ignoreDelete:
- if item.name.startswith(filteritem):
- ignoreDeleteDo = True
- if ignoreDeleteDo is False:
- item.delete()
- self._labels = None
-
- # check the colors
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- # we recognise the label
- self._log_info("check color of repo:%s labelname:'%s'" % (self.fullname, item.name))
- color = self.get_color(item.name)
- if item.color != color:
- self._log_info("change label color for repo %s %s" % (item.name, color))
- item.edit(item.name, color)
- self._labels = None
-
- def getlabel(self, name):
- for item in self.labels:
- self._log_info("%s:look for name:'%s'" % (item.name, name))
- if item.name == name:
- return item
- raise Exception("Dit not find label: '%s'" % name)
-
- def get_issue_from_markdown(self, issueNumber, markdown):
- i = self.get_issue(issueNumber, False)
- i._loadMD(markdown)
- self.issues.append(i)
- return i
-
- def get_issue(self, issueNumber, die=True):
- for issue in self.issues:
- if issue.number == issueNumber:
- return issue
- # not found in cache, try to load from github
- github_issue = self.api.get_issue(issueNumber)
-
- if github_issue:
- issue = Issue(repo=self, githubObj=github_issue)
- self._issues.append(issue)
- return issue
-
- if die:
- raise Exception("cannot find issue:%s in repo:%s" % (issueNumber, self))
- else:
- i = Issue(self)
- i._ddict["number"] = issueNumber
- return i
-
- def issues_by_type(self, *types):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- issues = []
- for issue in self.issues:
- if issue.type in types:
- issues.append(issue)
-
- return issues
-
- def issues_by_state(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.states:
- res[item] = []
- for issue in self.issues:
- if issue.state == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
- def issues_by_priority(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.priorities:
- res[item] = []
- for issue in self.issues:
- if issue.priority == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
- def issues_by_type_state(self, filter=None, collapsepriority=True):
- """
- filter is method which takes issue as argument and returns True or False to include
- returns dict of dict keys: type, state and then issues sorted following priority
- """
- res = {}
- for type in self.types:
- res[type] = {}
- for state in self.states:
- res[type][state] = {}
- for priority in self.priorities:
- res[type][state][priority] = []
- for issue in self.issues:
- if issue.type == type and issue.state == state:
- if filter is None or filter(issue):
- res[type][state][priority].append(issue)
- if collapsepriority:
- # sort the issues following priority
- temp = res[type][state]
- res[type][state] = []
- for priority in self.priorities:
- for subitem in temp[priority]:
- res[type][state].append(subitem)
- return res
-
- @property
- def types(self):
- return GithubRepo.TYPES
-
- @property
- def priorities(self):
- return GithubRepo.PRIORITIES
-
- @property
- def states(self):
- return GithubRepo.STATES
-
- @property
- def milestones(self):
- if self._milestones is None:
- self._milestones = [RepoMilestone(self, x) for x in self.api.get_milestones()]
-
- return self._milestones
-
- @property
- def milestone_titles(self):
- return [item.title for item in self.milestones]
-
- @property
- def milestone_names(self):
- return [item.name for item in self.milestones]
-
- def get_milestone(self, name, die=True):
- name = name.strip()
- if name == "":
- raise Exception("Name cannot be empty.")
- for item in self.milestones:
- if name == item.name.strip() or name == item.title.strip():
- return item
- if die:
- raise Exception("Could not find milestone with name:%s" % name)
- else:
- return None
-
- def create_milestone(self, name, title, description="", deadline="", owner=""):
- self._log_info('Attempt to create milestone "%s" [%s] deadline %s' % (name, title, deadline))
-
- def getBody(descr, name, owner):
- out = "%s\n\n" % descr
- out += "## name:%s\n" % name
- out += "## owner:%s\n" % owner
- return out
-
- ms = None
- for s in [name, title]:
- ms = self.get_milestone(s, die=False)
- if ms is not None:
- break
-
- if ms is not None:
- if ms.title != title:
- ms.title = title
- # if ms.deadline != deadline:
- # ms.deadline = deadline
- tocheck = getBody(description.strip(), name, owner)
- if ms.body.strip() != tocheck.strip():
- ms.body = tocheck
- else:
- # due = j.data.time.epoch2pythonDateTime(int(j.data.time.getEpochFuture(deadline)))
- self._log_info("Create milestone on %s: %s" % (self, title))
- body = getBody(description.strip(), name, owner)
- # workaround for https://github.com/PyGithub/PyGithub/issues/396
- milestone = self.api.create_milestone(title=title, description=body)
- milestone.edit(title=title)
-
- self._milestones.append(RepoMilestone(self, milestone))
-
- def delete_milestone(self, name):
- if name.strip() == "":
- raise Exception("Name cannot be empty.")
- self._log_info("Delete milestone on %s: '%s'" % (self, name))
- try:
- ms = self.get_milestone(name)
- ms.api.delete()
- self._milestones = []
- except Exception:
- self._log_info("Milestone '%s' doesn't exist. no need to delete" % name)
-
- def _labelsubset(self, cat):
- res = []
- for item in self.labels:
- if item.startswith(cat):
- item = item[len(cat) :].strip("_")
- res.append(item)
- res.sort()
- return res
-
- def get_color(self, name):
-
- # colors={'state_question':'fbca04',
- # 'priority_urgent':'d93f0b',
- # 'state_verification':'006b75',
- # 'priority_minor':'',
- # 'type_task':'',
- # 'type_feature':'',
- # 'process_wontfix':"ffffff",
- # 'priority_critical':"b60205",
- # 'state_inprogress':"e6e6e6",
- # 'priority_normal':"e6e6e6",
- # 'type_story':"ee9a00",
- # 'process_duplicate':"",
- # 'state_closed':"5319e7",
- # 'type_bug':"fc2929",
- # 'state_accepted':"0e8a16",
- # 'type_question':"fbca04",
- # 'state_new':"1d76db"}
-
- if name.startswith("state"):
- return "c2e0c6" # light green
-
- if name.startswith("process"):
- return "d4c5f9" # light purple
-
- if name.startswith("type"):
- return "fef2c0" # light yellow
-
- if name in ("priority_critical", "task_no_estimation"):
- return "b60205" # red
-
- if name.startswith("priority_urgent"):
- return "d93f0b"
-
- if name.startswith("priority"):
- return "f9d0c4" # roze
-
- return "ffffff"
-
- def set_file(self, path, content, message="update file"):
- """
- Creates or updates the file content at path with given content
- :param path: file path `README.md`
- :param content: Plain content of file
- :return:
- """
- bytes = content.encode()
- encoded = base64.encodebytes(bytes)
-
- params = {"message": message, "content": encoded.decode()}
-
- path = urllib.parse.quote(path)
- try:
- obj = self.api.get_contents(path)
- params["sha"] = obj.sha
- if base64.decodebytes(obj.content.encode()) == bytes:
- return
- except UnknownObjectException:
- pass
-
- self._log_info('Updating file "%s"' % path)
- self.api._requester.requestJsonAndCheck("PUT", self.api.url + "/contents/" + path, input=params)
-
- @property
- def issues(self):
- with self._lock:
- if self._issues is None:
- issues = []
- for item in self.api.get_issues(state="all"):
- issues.append(Issue(self, githubObj=item))
-
- self._issues = issues
-
- return self._issues
-
- def __str__(self):
- return "gitrepo:%s" % self.fullname
-
- __repr__ = __str__
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class GithubRepo
-(client, fullname)
-
-
-
-
-Source code
-
class GithubRepo:
- TYPES = ["story", "ticket", "task", "bug", "feature", "question", "monitor", "unknown"]
- PRIORITIES = ["critical", "urgent", "normal", "minor"]
-
- STATES = ["new", "accepted", "question", "inprogress", "verification", "closed"]
-
- def __init__(self, client, fullname):
- self.client = client
- self.fullname = fullname
- self._repoclient = None
- self._labels = None
- self._issues = None
- self._lock = threading.RLock()
- self._milestones = None
-
- def _log_info(self, s):
- pass
-
- @property
- def api(self):
- if self._repoclient is None:
- self._repoclient = self.client.get_repo(self.fullname)
- return self._repoclient
-
- @property
- def name(self):
- return self.fullname.split("/", 1)[-1]
-
- @property
- def type(self):
- if self.name in ["home"]:
- return "home"
- elif self.name.startswith("proj"):
- return "proj"
- elif self.name.startswith("org_"):
- return "org"
- elif self.name.startswith("www"):
- return "www"
- elif self.name.startswith("doc"):
- return "doc"
- elif self.name.startswith("cockpit"):
- return "cockpit"
- else:
- return "code"
-
- @property
- def labelnames(self):
- return [item.name for item in self.labels]
-
- @property
- def labels(self):
- with self._lock:
- if self._labels is None:
- self._labels = [item for item in self.api.get_labels()]
-
- return self._labels
-
- @property
- def stories(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("story")
-
- @property
- def tasks(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("task")
-
- def labelsSet(self, labels2set, ignoreDelete=["p_"], delete=True):
- """
- @param ignore all labels starting with ignore will not be deleted
- """
-
- for item in labels2set:
- if not isinstance(item, str):
- raise Exception("Labels to set need to be in string format, found:%s" % labels2set)
-
- # walk over github existing labels
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- name = item.name.lower()
- if name not in labels2set:
- # label in repo does not correspond to label we need
- if name in replacelabels:
- nameNew = replacelabels[item.name.lower()]
- if nameNew not in self.labelnames:
- color = self.get_color(name)
- self._log_info(
- "change label in repo: %s oldlabel:'%s' to:'%s' color:%s"
- % (self.fullname, item.name, nameNew, color)
- )
- item.edit(nameNew, color)
- self._labels = None
- else:
- # no replacement
- name = "type_unknown"
- color = self.get_color(name)
- try:
- item.edit(name, color)
- except BaseException:
- item.delete()
- self._labels = None
-
- # walk over new labels we need to set
- for name in labels2set:
- if name not in self.labelnames:
- # does not exist yet in repo
- color = self.get_color(name)
- self._log_info("create label: %s %s %s" % (self.fullname, name, color))
- self.api.create_label(name, color)
- self._labels = None
-
- name = ""
-
- if delete:
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- if item.name not in labels2set:
- self._log_info("delete label: %s %s" % (self.fullname, item.name))
- ignoreDeleteDo = False
- for filteritem in ignoreDelete:
- if item.name.startswith(filteritem):
- ignoreDeleteDo = True
- if ignoreDeleteDo is False:
- item.delete()
- self._labels = None
-
- # check the colors
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- # we recognise the label
- self._log_info("check color of repo:%s labelname:'%s'" % (self.fullname, item.name))
- color = self.get_color(item.name)
- if item.color != color:
- self._log_info("change label color for repo %s %s" % (item.name, color))
- item.edit(item.name, color)
- self._labels = None
-
- def getlabel(self, name):
- for item in self.labels:
- self._log_info("%s:look for name:'%s'" % (item.name, name))
- if item.name == name:
- return item
- raise Exception("Dit not find label: '%s'" % name)
-
- def get_issue_from_markdown(self, issueNumber, markdown):
- i = self.get_issue(issueNumber, False)
- i._loadMD(markdown)
- self.issues.append(i)
- return i
-
- def get_issue(self, issueNumber, die=True):
- for issue in self.issues:
- if issue.number == issueNumber:
- return issue
- # not found in cache, try to load from github
- github_issue = self.api.get_issue(issueNumber)
-
- if github_issue:
- issue = Issue(repo=self, githubObj=github_issue)
- self._issues.append(issue)
- return issue
-
- if die:
- raise Exception("cannot find issue:%s in repo:%s" % (issueNumber, self))
- else:
- i = Issue(self)
- i._ddict["number"] = issueNumber
- return i
-
- def issues_by_type(self, *types):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- issues = []
- for issue in self.issues:
- if issue.type in types:
- issues.append(issue)
-
- return issues
-
- def issues_by_state(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.states:
- res[item] = []
- for issue in self.issues:
- if issue.state == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
- def issues_by_priority(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.priorities:
- res[item] = []
- for issue in self.issues:
- if issue.priority == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
- def issues_by_type_state(self, filter=None, collapsepriority=True):
- """
- filter is method which takes issue as argument and returns True or False to include
- returns dict of dict keys: type, state and then issues sorted following priority
- """
- res = {}
- for type in self.types:
- res[type] = {}
- for state in self.states:
- res[type][state] = {}
- for priority in self.priorities:
- res[type][state][priority] = []
- for issue in self.issues:
- if issue.type == type and issue.state == state:
- if filter is None or filter(issue):
- res[type][state][priority].append(issue)
- if collapsepriority:
- # sort the issues following priority
- temp = res[type][state]
- res[type][state] = []
- for priority in self.priorities:
- for subitem in temp[priority]:
- res[type][state].append(subitem)
- return res
-
- @property
- def types(self):
- return GithubRepo.TYPES
-
- @property
- def priorities(self):
- return GithubRepo.PRIORITIES
-
- @property
- def states(self):
- return GithubRepo.STATES
-
- @property
- def milestones(self):
- if self._milestones is None:
- self._milestones = [RepoMilestone(self, x) for x in self.api.get_milestones()]
-
- return self._milestones
-
- @property
- def milestone_titles(self):
- return [item.title for item in self.milestones]
-
- @property
- def milestone_names(self):
- return [item.name for item in self.milestones]
-
- def get_milestone(self, name, die=True):
- name = name.strip()
- if name == "":
- raise Exception("Name cannot be empty.")
- for item in self.milestones:
- if name == item.name.strip() or name == item.title.strip():
- return item
- if die:
- raise Exception("Could not find milestone with name:%s" % name)
- else:
- return None
-
- def create_milestone(self, name, title, description="", deadline="", owner=""):
- self._log_info('Attempt to create milestone "%s" [%s] deadline %s' % (name, title, deadline))
-
- def getBody(descr, name, owner):
- out = "%s\n\n" % descr
- out += "## name:%s\n" % name
- out += "## owner:%s\n" % owner
- return out
-
- ms = None
- for s in [name, title]:
- ms = self.get_milestone(s, die=False)
- if ms is not None:
- break
-
- if ms is not None:
- if ms.title != title:
- ms.title = title
- # if ms.deadline != deadline:
- # ms.deadline = deadline
- tocheck = getBody(description.strip(), name, owner)
- if ms.body.strip() != tocheck.strip():
- ms.body = tocheck
- else:
- # due = j.data.time.epoch2pythonDateTime(int(j.data.time.getEpochFuture(deadline)))
- self._log_info("Create milestone on %s: %s" % (self, title))
- body = getBody(description.strip(), name, owner)
- # workaround for https://github.com/PyGithub/PyGithub/issues/396
- milestone = self.api.create_milestone(title=title, description=body)
- milestone.edit(title=title)
-
- self._milestones.append(RepoMilestone(self, milestone))
-
- def delete_milestone(self, name):
- if name.strip() == "":
- raise Exception("Name cannot be empty.")
- self._log_info("Delete milestone on %s: '%s'" % (self, name))
- try:
- ms = self.get_milestone(name)
- ms.api.delete()
- self._milestones = []
- except Exception:
- self._log_info("Milestone '%s' doesn't exist. no need to delete" % name)
-
- def _labelsubset(self, cat):
- res = []
- for item in self.labels:
- if item.startswith(cat):
- item = item[len(cat) :].strip("_")
- res.append(item)
- res.sort()
- return res
-
- def get_color(self, name):
-
- # colors={'state_question':'fbca04',
- # 'priority_urgent':'d93f0b',
- # 'state_verification':'006b75',
- # 'priority_minor':'',
- # 'type_task':'',
- # 'type_feature':'',
- # 'process_wontfix':"ffffff",
- # 'priority_critical':"b60205",
- # 'state_inprogress':"e6e6e6",
- # 'priority_normal':"e6e6e6",
- # 'type_story':"ee9a00",
- # 'process_duplicate':"",
- # 'state_closed':"5319e7",
- # 'type_bug':"fc2929",
- # 'state_accepted':"0e8a16",
- # 'type_question':"fbca04",
- # 'state_new':"1d76db"}
-
- if name.startswith("state"):
- return "c2e0c6" # light green
-
- if name.startswith("process"):
- return "d4c5f9" # light purple
-
- if name.startswith("type"):
- return "fef2c0" # light yellow
-
- if name in ("priority_critical", "task_no_estimation"):
- return "b60205" # red
-
- if name.startswith("priority_urgent"):
- return "d93f0b"
-
- if name.startswith("priority"):
- return "f9d0c4" # roze
-
- return "ffffff"
-
- def set_file(self, path, content, message="update file"):
- """
- Creates or updates the file content at path with given content
- :param path: file path `README.md`
- :param content: Plain content of file
- :return:
- """
- bytes = content.encode()
- encoded = base64.encodebytes(bytes)
-
- params = {"message": message, "content": encoded.decode()}
-
- path = urllib.parse.quote(path)
- try:
- obj = self.api.get_contents(path)
- params["sha"] = obj.sha
- if base64.decodebytes(obj.content.encode()) == bytes:
- return
- except UnknownObjectException:
- pass
-
- self._log_info('Updating file "%s"' % path)
- self.api._requester.requestJsonAndCheck("PUT", self.api.url + "/contents/" + path, input=params)
-
- @property
- def issues(self):
- with self._lock:
- if self._issues is None:
- issues = []
- for item in self.api.get_issues(state="all"):
- issues.append(Issue(self, githubObj=item))
-
- self._issues = issues
-
- return self._issues
-
- def __str__(self):
- return "gitrepo:%s" % self.fullname
-
- __repr__ = __str__
-
-
Class variables
-
-
var PRIORITIES
-
-
-
-
var STATES
-
-
-
-
var TYPES
-
-
-
-
-
Instance variables
-
-
var api
-
-
-
-Source code
-
@property
-def api(self):
- if self._repoclient is None:
- self._repoclient = self.client.get_repo(self.fullname)
- return self._repoclient
-
-
-
var issues
-
-
-
-Source code
-
@property
-def issues(self):
- with self._lock:
- if self._issues is None:
- issues = []
- for item in self.api.get_issues(state="all"):
- issues.append(Issue(self, githubObj=item))
-
- self._issues = issues
-
- return self._issues
-
-
-
var labelnames
-
-
-
-Source code
-
@property
-def labelnames(self):
- return [item.name for item in self.labels]
-
-
-
var labels
-
-
-
-Source code
-
@property
-def labels(self):
- with self._lock:
- if self._labels is None:
- self._labels = [item for item in self.api.get_labels()]
-
- return self._labels
-
-
-
var milestone_names
-
-
-
-Source code
-
@property
-def milestone_names(self):
- return [item.name for item in self.milestones]
-
-
-
var milestone_titles
-
-
-
-Source code
-
@property
-def milestone_titles(self):
- return [item.title for item in self.milestones]
-
-
-
var milestones
-
-
-
-Source code
-
@property
-def milestones(self):
- if self._milestones is None:
- self._milestones = [RepoMilestone(self, x) for x in self.api.get_milestones()]
-
- return self._milestones
@property
-def stories(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("story")
-
-
-
var tasks
-
-
-
-Source code
-
@property
-def tasks(self):
- # walk overall issues find the stories (based on type)
- # only for home type repo, otherwise return []
- return self.issues_by_type("task")
def get_issue_from_markdown(self, issueNumber, markdown):
- i = self.get_issue(issueNumber, False)
- i._loadMD(markdown)
- self.issues.append(i)
- return i
-
-
-
-def get_milestone(self, name, die=True)
-
-
-
-
-Source code
-
def get_milestone(self, name, die=True):
- name = name.strip()
- if name == "":
- raise Exception("Name cannot be empty.")
- for item in self.milestones:
- if name == item.name.strip() or name == item.title.strip():
- return item
- if die:
- raise Exception("Could not find milestone with name:%s" % name)
- else:
- return None
-
-
-
-def getlabel(self, name)
-
-
-
-
-Source code
-
def getlabel(self, name):
- for item in self.labels:
- self._log_info("%s:look for name:'%s'" % (item.name, name))
- if item.name == name:
- return item
- raise Exception("Dit not find label: '%s'" % name)
-
-
-
-def issues_by_priority(self, filter=None)
-
-
-
filter is method which takes
-issue as argument and returns True or False to include
-
-Source code
-
def issues_by_priority(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.priorities:
- res[item] = []
- for issue in self.issues:
- if issue.priority == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
-
-
-def issues_by_state(self, filter=None)
-
-
-
filter is method which takes
-issue as argument and returns True or False to include
-
-Source code
-
def issues_by_state(self, filter=None):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- res = {}
- for item in self.states:
- res[item] = []
- for issue in self.issues:
- if issue.state == item:
- if filter is None or filter(issue):
- res[item].append(issue)
- return res
-
-
-
-def issues_by_type(self, *types)
-
-
-
filter is method which takes
-issue as argument and returns True or False to include
-
-Source code
-
def issues_by_type(self, *types):
- """
- filter is method which takes issue as argument and returns True or False to include
- """
- issues = []
- for issue in self.issues:
- if issue.type in types:
- issues.append(issue)
-
- return issues
filter is method which takes
-issue as argument and returns True or False to include
-returns dict of dict keys: type, state and then issues sorted following priority
-
-Source code
-
def issues_by_type_state(self, filter=None, collapsepriority=True):
- """
- filter is method which takes issue as argument and returns True or False to include
- returns dict of dict keys: type, state and then issues sorted following priority
- """
- res = {}
- for type in self.types:
- res[type] = {}
- for state in self.states:
- res[type][state] = {}
- for priority in self.priorities:
- res[type][state][priority] = []
- for issue in self.issues:
- if issue.type == type and issue.state == state:
- if filter is None or filter(issue):
- res[type][state][priority].append(issue)
- if collapsepriority:
- # sort the issues following priority
- temp = res[type][state]
- res[type][state] = []
- for priority in self.priorities:
- for subitem in temp[priority]:
- res[type][state].append(subitem)
- return res
@param ignore all labels starting with ignore will not be deleted
-
-Source code
-
def labelsSet(self, labels2set, ignoreDelete=["p_"], delete=True):
- """
- @param ignore all labels starting with ignore will not be deleted
- """
-
- for item in labels2set:
- if not isinstance(item, str):
- raise Exception("Labels to set need to be in string format, found:%s" % labels2set)
-
- # walk over github existing labels
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- name = item.name.lower()
- if name not in labels2set:
- # label in repo does not correspond to label we need
- if name in replacelabels:
- nameNew = replacelabels[item.name.lower()]
- if nameNew not in self.labelnames:
- color = self.get_color(name)
- self._log_info(
- "change label in repo: %s oldlabel:'%s' to:'%s' color:%s"
- % (self.fullname, item.name, nameNew, color)
- )
- item.edit(nameNew, color)
- self._labels = None
- else:
- # no replacement
- name = "type_unknown"
- color = self.get_color(name)
- try:
- item.edit(name, color)
- except BaseException:
- item.delete()
- self._labels = None
-
- # walk over new labels we need to set
- for name in labels2set:
- if name not in self.labelnames:
- # does not exist yet in repo
- color = self.get_color(name)
- self._log_info("create label: %s %s %s" % (self.fullname, name, color))
- self.api.create_label(name, color)
- self._labels = None
-
- name = ""
-
- if delete:
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- if item.name not in labels2set:
- self._log_info("delete label: %s %s" % (self.fullname, item.name))
- ignoreDeleteDo = False
- for filteritem in ignoreDelete:
- if item.name.startswith(filteritem):
- ignoreDeleteDo = True
- if ignoreDeleteDo is False:
- item.delete()
- self._labels = None
-
- # check the colors
- labelstowalk = copy.copy(self.labels)
- for item in labelstowalk:
- # we recognise the label
- self._log_info("check color of repo:%s labelname:'%s'" % (self.fullname, item.name))
- color = self.get_color(item.name)
- if item.color != color:
- self._log_info("change label color for repo %s %s" % (item.name, color))
- item.edit(item.name, color)
- self._labels = None
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var admins
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var user
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var username
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
from jumpscale.loader import j
-import smtplib
-import mimetypes
-from email import encoders
-from email.mime.audio import MIMEAudio
-from email.mime.base import MIMEBase
-from email.mime.image import MIMEImage
-from email.mime.multipart import MIMEMultipart
-from email.mime.text import MIMEText
-
-from jumpscale.clients.base import Client
-from jumpscale.core.base import fields
-
-class MailClient(Client):
- name = fields.String()
- smtp_server = fields.String()
- smtp_port = fields.Integer()
- login = fields.String()
- password = fields.String()
- sender_email = fields.String()
-
- def __init__(self):
- super().__init__()
-
- @property
- def is_ssl(self):
- self.smtp_port in [465, 587]
-
- def send(self, recipients, sender="", subject="", message="", files=None, mimetype=None):
- """ Send an email to the recipients from the sender containing the message required and any attached files given by the paths in files
- :param recipients: Recipients of the message
- :type recipients: mixed, str or list
- :param sender: Sender of the email
- :type sender: str
- :param subject: Subject of the email
- :type subject: str
- :param message: Body of the email
- :type message: str
- :param files: List of paths to files to attach
- :type files: list of strings
- :param mimetype: Type of the body plain, html or None for autodetection
- :type mimetype: str
- """
- if not sender:
- sender = self.sender_email
- if isinstance(recipients, str):
- recipients = [recipients]
- server = smtplib.SMTP(self.smtp_server, self.smtp_port)
- server.ehlo()
- if self._ssl:
- server.starttls()
- if self.login:
- server.login(self.login, self.password)
-
- if mimetype is None:
- if "<html>" in message:
- mimetype = "html"
- else:
- mimetype = "plain"
-
- msg = MIMEText(message, mimetype)
-
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
-
- if files:
- txtmsg = msg
- msg = MIMEMultipart()
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
- msg.attach(txtmsg)
- for fl in files:
- # Guess the content type based on the file's extension. Encoding
- # will be ignored, although we should check for simple things like
- # gzip'd or compressed files.
- filename = j.sals.fs.basename(fl)
- ctype, encoding = mimetypes.guess_type(fl)
- content = j.sals.fs.read_file(fl)
- if ctype is None or encoding is not None:
- # No guess could be made, or the file is encoded (compressed), so
- # use a generic bag-of-bits type.
- ctype = "application/octet-stream"
- maintype, subtype = ctype.split("/", 1)
- if maintype == "text":
- attachement = MIMEText(content, _subtype=subtype)
- elif maintype == "image":
- attachement = MIMEImage(content, _subtype=subtype)
- elif maintype == "audio":
- attachement = MIMEAudio(content, _subtype=subtype)
- else:
- attachement = MIMEBase(maintype, subtype)
- attachement.set_payload(content)
- # Encode the payload using Base64
- encoders.encode_base64(attachement)
- # Set the filename parameter
- attachement.add_header("Content-Disposition", "attachment", filename=filename)
- msg.attach(attachement)
- server.sendmail(sender, recipients, msg.as_string())
- server.close()
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class MailClient
-
-
-
A simple attribute-based namespace.
-
SimpleNamespace(**kwargs)
-
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class MailClient(Client):
- name = fields.String()
- smtp_server = fields.String()
- smtp_port = fields.Integer()
- login = fields.String()
- password = fields.String()
- sender_email = fields.String()
-
- def __init__(self):
- super().__init__()
-
- @property
- def is_ssl(self):
- self.smtp_port in [465, 587]
-
- def send(self, recipients, sender="", subject="", message="", files=None, mimetype=None):
- """ Send an email to the recipients from the sender containing the message required and any attached files given by the paths in files
- :param recipients: Recipients of the message
- :type recipients: mixed, str or list
- :param sender: Sender of the email
- :type sender: str
- :param subject: Subject of the email
- :type subject: str
- :param message: Body of the email
- :type message: str
- :param files: List of paths to files to attach
- :type files: list of strings
- :param mimetype: Type of the body plain, html or None for autodetection
- :type mimetype: str
- """
- if not sender:
- sender = self.sender_email
- if isinstance(recipients, str):
- recipients = [recipients]
- server = smtplib.SMTP(self.smtp_server, self.smtp_port)
- server.ehlo()
- if self._ssl:
- server.starttls()
- if self.login:
- server.login(self.login, self.password)
-
- if mimetype is None:
- if "<html>" in message:
- mimetype = "html"
- else:
- mimetype = "plain"
-
- msg = MIMEText(message, mimetype)
-
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
-
- if files:
- txtmsg = msg
- msg = MIMEMultipart()
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
- msg.attach(txtmsg)
- for fl in files:
- # Guess the content type based on the file's extension. Encoding
- # will be ignored, although we should check for simple things like
- # gzip'd or compressed files.
- filename = j.sals.fs.basename(fl)
- ctype, encoding = mimetypes.guess_type(fl)
- content = j.sals.fs.read_file(fl)
- if ctype is None or encoding is not None:
- # No guess could be made, or the file is encoded (compressed), so
- # use a generic bag-of-bits type.
- ctype = "application/octet-stream"
- maintype, subtype = ctype.split("/", 1)
- if maintype == "text":
- attachement = MIMEText(content, _subtype=subtype)
- elif maintype == "image":
- attachement = MIMEImage(content, _subtype=subtype)
- elif maintype == "audio":
- attachement = MIMEAudio(content, _subtype=subtype)
- else:
- attachement = MIMEBase(maintype, subtype)
- attachement.set_payload(content)
- # Encode the payload using Base64
- encoders.encode_base64(attachement)
- # Set the filename parameter
- attachement.add_header("Content-Disposition", "attachment", filename=filename)
- msg.attach(attachement)
- server.sendmail(sender, recipients, msg.as_string())
- server.close()
@property
-def is_ssl(self):
- self.smtp_port in [465, 587]
-
-
-
var login
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var name
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var password
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var sender_email
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var smtp_port
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var smtp_server
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
Send an email to the recipients from the sender containing the message required and any attached files given by the paths in files
-:param recipients: Recipients of the message
-:type recipients: mixed, str or list
-:param sender: Sender of the email
-:type sender: str
-:param subject: Subject of the email
-:type subject: str
-:param message: Body of the email
-:type message: str
-:param files: List of paths to files to attach
-:type files: list of strings
-:param mimetype: Type of the body plain, html or None for autodetection
-:type mimetype: str
-
-Source code
-
def send(self, recipients, sender="", subject="", message="", files=None, mimetype=None):
- """ Send an email to the recipients from the sender containing the message required and any attached files given by the paths in files
- :param recipients: Recipients of the message
- :type recipients: mixed, str or list
- :param sender: Sender of the email
- :type sender: str
- :param subject: Subject of the email
- :type subject: str
- :param message: Body of the email
- :type message: str
- :param files: List of paths to files to attach
- :type files: list of strings
- :param mimetype: Type of the body plain, html or None for autodetection
- :type mimetype: str
- """
- if not sender:
- sender = self.sender_email
- if isinstance(recipients, str):
- recipients = [recipients]
- server = smtplib.SMTP(self.smtp_server, self.smtp_port)
- server.ehlo()
- if self._ssl:
- server.starttls()
- if self.login:
- server.login(self.login, self.password)
-
- if mimetype is None:
- if "<html>" in message:
- mimetype = "html"
- else:
- mimetype = "plain"
-
- msg = MIMEText(message, mimetype)
-
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
-
- if files:
- txtmsg = msg
- msg = MIMEMultipart()
- msg["Subject"] = subject
- msg["From"] = sender
- msg["To"] = ",".join(recipients)
- msg.attach(txtmsg)
- for fl in files:
- # Guess the content type based on the file's extension. Encoding
- # will be ignored, although we should check for simple things like
- # gzip'd or compressed files.
- filename = j.sals.fs.basename(fl)
- ctype, encoding = mimetypes.guess_type(fl)
- content = j.sals.fs.read_file(fl)
- if ctype is None or encoding is not None:
- # No guess could be made, or the file is encoded (compressed), so
- # use a generic bag-of-bits type.
- ctype = "application/octet-stream"
- maintype, subtype = ctype.split("/", 1)
- if maintype == "text":
- attachement = MIMEText(content, _subtype=subtype)
- elif maintype == "image":
- attachement = MIMEImage(content, _subtype=subtype)
- elif maintype == "audio":
- attachement = MIMEAudio(content, _subtype=subtype)
- else:
- attachement = MIMEBase(maintype, subtype)
- attachement.set_payload(content)
- # Encode the payload using Base64
- encoders.encode_base64(attachement)
- # Set the filename parameter
- attachement.add_header("Content-Disposition", "attachment", filename=filename)
- msg.attach(attachement)
- server.sendmail(sender, recipients, msg.as_string())
- server.close()
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var address
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var bucket
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var create_bucket
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var name
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var port
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var secret_key
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
Download and save the object as a file in the local filesystem
-
:param bucket_name: name of bucket
-:type bucket_name: str
-:param object_name: name of object
-:type object_name: str
-:param file_path: local path to which object data will be written
-:type file_path: str
-:return: object stat info (includes: size, etag, content_type,last_modified, metadata)
-:rtype: Object
-
-Source code
-
def download(self, bucket_name, object_name, file_path):
- """Download and save the object as a file in the local filesystem
-
- :param bucket_name: name of bucket
- :type bucket_name: str
- :param object_name: name of object
- :type object_name: str
- :param file_path: local path to which object data will be written
- :type file_path: str
- :return: object stat info (includes: size, etag, content_type,last_modified, metadata)
- :rtype: Object
- """
-
- return self.client.fget_object(bucket_name, object_name, file_path)
-
-
-
-def list_buckets(self)
-
-
-
List all buckets
-
:return: bucketList, bucket.name, bucket.creation_date
-:rtype: function, str, date
:param bucket_name: name of bucket
-:type bucket_name: str
-:param prefix: prefix of the objects that should be listed, defaults to None
-:type prefix: str, optional
-:param recursive: True indicates recursive style listing and False indicates directory style listing delimited by '/', defaults to None
-:type recursive: bool, optional
-:return: Iterator for all the objects in the bucket (includes: bucket_name, object_name,is_dir, size, etag, last_modified)
-:rtype: Object
-
-Source code
-
def list_objects(self, bucket_name, prefix=None, recursive=None):
- """List objects in a specific bucket
-
- :param bucket_name: name of bucket
- :type bucket_name: str
- :param prefix: prefix of the objects that should be listed, defaults to None
- :type prefix: str, optional
- :param recursive: True indicates recursive style listing and False indicates directory style listing delimited by '/', defaults to None
- :type recursive: bool, optional
- :return: Iterator for all the objects in the bucket (includes: bucket_name, object_name,is_dir, size, etag, last_modified)
- :rtype: Object
- """
-
- return self.client.list_objects(bucket_name, prefix=prefix, recursive=recursive)
-
-
-
-def remove_bucket(self, bucket_name)
-
-
-
Remove a bucket.
-
:param bucket_name: name of bucket to be removed
-:type bucket_name: str
-
-Source code
-
def remove_bucket(self, bucket_name):
- """Remove a bucket.
-
- :param bucket_name: name of bucket to be removed
- :type bucket_name: str
- """
- return self.client.remove_bucket(bucket_name)
Upload contents from a file specified by file_path, to object_name
-
:param bucket_name: name of bucket
-:type bucket_name: str
-:param object_name: name of object
-:type object_name: str
-:param file_path: local path from which object data will be read
-:type file_path: str
-:param content_type: content type of the object, defaults to 'text/plain'
-:type content_type: str, optional
-:param meta_data: additional metadata, defaults to None
-:type meta_data: dict, optional
-:raises ValueError: if file given by file_path is not found
-:return: str
-:rtype: Object etag computed by the minio server.
-
-Source code
-
def upload(self, bucket_name, object_name, file_path, content_type="text/plain", meta_data=None):
- """Upload contents from a file specified by file_path, to object_name
-
- :param bucket_name: name of bucket
- :type bucket_name: str
- :param object_name: name of object
- :type object_name: str
- :param file_path: local path from which object data will be read
- :type file_path: str
- :param content_type: content type of the object, defaults to 'text/plain'
- :type content_type: str, optional
- :param meta_data: additional metadata, defaults to None
- :type meta_data: dict, optional
- :raises ValueError: if file given by file_path is not found
- :return: str
- :rtype: Object etag computed by the minio server.
- """
- if not j.sals.fs.exists(file_path):
- raise j.exceptions.Value("file: {} not found".format(file_path))
- return self.client.fput_object(bucket_name, object_name, file_path, content_type, meta_data)
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
@property
-def client_ingest(self):
- if not self.cached_client_ingest:
- self.cached_client_ingest = IngestClient(host=self.host, port=self.port, password=self.password)
- return self.cached_client_ingest
-
-
-
var client_search
-
-
-
-Source code
-
@property
-def client_search(self):
- if not self.cached_client_search:
- self.cached_client_search = SearchClient(host=self.host, port=self.port, password=self.password)
- return self.cached_client_search
-
-
-
var host
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var password
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var port
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var config
-
-
-
-Source code
-
@property
-def config(self):
- if not self.__config:
- self.__config = self._call("system/config")
- return self.__config
-
-
-
var host
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var port
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var acess_token_secret
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var api_key_
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var name
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var secret
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var trello_client
-
-
-
-Source code
-
@property
-def trello_client(self):
-
- if not self.token_secret:
- # print("**WILL TRY TO DO OAUTH SESSION")
- access_token = create_oauth_token(key=self.api_key, secret=self.secret)
- self.access_token_ = access_token["oauth_token"]
- self.access_token_secret = access_token["oauth_token_secret"]
-
- self.client = TrelloAPIClient(api_key=self.api_key_, api_secret=self.secret, token=self.token, token_secret=self.token_secret)
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var auth_token
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var twilio_rest_client
-
-
-
-Source code
-
@property
-def twilio_rest_client(self):
- if not self.__client:
- self.__client = TwilioRestClient(self.account_sid, self.auth_token)
- return self.__client
send sms
-Your Account Sid and Auth Token from twilio.com/console
-DANGER! This is insecure. See http://twil.io/secure
-
Arguments
-
body (string) : the sms text
-sender (text) : sender full number ex: +15558675310
-Keyword Arguments:
-recievers (list) : recievers phone numbers
-
-Source code
-
def send_sms(self, body, sender, recievers=None):
- """send sms
- Your Account Sid and Auth Token from twilio.com/console
- DANGER! This is insecure. See http://twil.io/secure
- Arguments:
- body (string) : the sms text
- sender (text) : sender full number ex: +15558675310
-
- Keyword Arguments:
- recievers (list) : recievers phone numbers
- """
- recievers = recievers or []
- for r in recievers:
- message = self.twilio_rest_client.messages.create(body=body, from_=sender, to=r)
- print(message.sid)
def authorize(self):
- """Authorize member to the zerotier network
- """
- self._update_authorization(True)
-
-
-
-def unauthorize(self)
-
-
-
Unauthorize member to the zerotier network
-
-Source code
-
def unauthorize(self):
- """Unauthorize member to the zerotier network
- """
- self._update_authorization(False)
-
-
-
-
-
-class Network
-(network_data, client)
-
-
-
-
-Source code
-
class Network:
- def __init__(self, network_data, client):
- self.id = network_data["id"]
- self._client = client
- self.raw_data = network_data
-
- @property
- def name(self):
- return self.raw_data["config"]["name"]
-
- @property
- def routes(self):
- return self.raw_data["config"]["routes"]
-
- def list_members(self):
- """List all members of that network
-
- Returns:
- list: List of all members
- """
- return [Member(member, self) for member in self._client._send_request(f"network/{self.id}/member")]
-
- def add_member(self, address, name=None, private_ip=None, authorized=True):
- """Add a member to the network
-
- Args:
- address (str): Address of the member
- name (str, optional): Name of the member. Defaults to None.
- private_ip (str, optional): Private IP to assign. Defaults to None.
- authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
-
- Returns:
- Member: Added member
- """
- data = {"config": {"authorized": authorized}, "name": name}
- if private_ip:
- data["config"]["ipAssignments"] = [private_ip]
- member_data = self._client._send_request(f"network/{self.id}/member/{address}", method="post", data=data)
- return Member(member_data, self, address)
-
- def update_member(self, address, name=None, private_ip=None, authorized=None):
- """Update a member in the network
-
- Args:
- address (str): Address of the member
- name (str, optional): Name of the member. Defaults to None.
- private_ip (str, optional): Private IP to assign. Defaults to None.
- authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
-
- Returns:
- Member: Added member
- """
- return self.add_member(address, name, private_ip, authorized)
-
- def get_member(self, address):
- """Returns member by address
-
- Args:
- address (str): Member address
-
- Returns:
- Member: Found member
- """
- return Member(self._client._send_request(f"network/{self.id}/member/{address}"), self, address)
-
- def delete_member(self, address):
- """Deletes a member
-
- Args:
- address (str): Member address
- """
- self._client._send_request(f"network/{self.id}/member/{address}", method="delete", return_json=False)
-
- def __repr__(self):
- return f"Network({self.id})"
def add_member(self, address, name=None, private_ip=None, authorized=True):
- """Add a member to the network
-
- Args:
- address (str): Address of the member
- name (str, optional): Name of the member. Defaults to None.
- private_ip (str, optional): Private IP to assign. Defaults to None.
- authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
-
- Returns:
- Member: Added member
- """
- data = {"config": {"authorized": authorized}, "name": name}
- if private_ip:
- data["config"]["ipAssignments"] = [private_ip]
- member_data = self._client._send_request(f"network/{self.id}/member/{address}", method="post", data=data)
- return Member(member_data, self, address)
-
-
-
-def delete_member(self, address)
-
-
-
Deletes a member
-
Args
-
-
address : str
-
Member address
-
-
-Source code
-
def delete_member(self, address):
- """Deletes a member
-
- Args:
- address (str): Member address
- """
- self._client._send_request(f"network/{self.id}/member/{address}", method="delete", return_json=False)
def get_member(self, address):
- """Returns member by address
-
- Args:
- address (str): Member address
-
- Returns:
- Member: Found member
- """
- return Member(self._client._send_request(f"network/{self.id}/member/{address}"), self, address)
-
-
-
-def list_members(self)
-
-
-
List all members of
-that network
-
Returns
-
-
list
-
List of all members
-
-
-Source code
-
def list_members(self):
- """List all members of that network
-
- Returns:
- list: List of all members
- """
- return [Member(member, self) for member in self._client._send_request(f"network/{self.id}/member")]
def update_member(self, address, name=None, private_ip=None, authorized=None):
- """Update a member in the network
-
- Args:
- address (str): Address of the member
- name (str, optional): Name of the member. Defaults to None.
- private_ip (str, optional): Private IP to assign. Defaults to None.
- authorized (bool, optional): Whether to authorize the user or not. Defaults to True.
-
- Returns:
- Member: Added member
- """
- return self.add_member(address, name, private_ip, authorized)
-
-
-
-
-
-class ZerotierClient
-
-
-
A simple attribute-based namespace.
-
SimpleNamespace(**kwargs)
-
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
-
any instance can have an optional name and a parent.
-
class Person(Base):
- name = fields.String()
- age = fields.Float()
-
-p = Person(name="ahmed", age="19")
-print(p.name, p.age)
-
-
Args
-
-
parent_ : Base, optional
-
parent instance. Defaults to None.
-
instance_name_ : str, optional
-
instance name. Defaults to None.
-
**values
-
any given field values to initiate the instance with
-
-
-Source code
-
class ZerotierClient(Client):
- base_url = fields.String(default="https://my.zerotier.com/api")
- token = fields.String()
-
- def __init__(self):
- super().__init__()
- self._session = None
-
- def _send_request(self, path, method="get", data=None, return_json=True):
- url = f"{self.base_url}/{path}"
- func_method = getattr(self.session, method)
- res = func_method(url, json=data)
- res.raise_for_status()
- if return_json:
- return res.json()
- else:
- return res.content
-
- @property
- def session(self):
- if not self._session:
- if not self.token:
- raise j.exceptions.Value("Please set token to use the client")
- self._session = requests.Session()
- self._session.headers["Authorization"] = f"Bearer {self.token}"
- return self._session
-
- def list_networks(self):
- """List networks available to user
-
- Returns:
- list: All available networks
- """
- return [Network(network, self) for network in self._send_request("network")]
-
- def get_network(self, network_id):
- """Get network by id
-
- Args:
- network_id (str): Network id
-
- Returns:
- Network: Found network
- """
- return Network(self._send_request(f"network/{network_id}"), self)
-
- def create_network(self, public, target_subnet=None, name=None, auto_assign=True):
- """Create a new network
-
- Args:
- public (bool): Specify if network is public or not
- target_subnet (str, optional): Target network to be pick assignment ips from. Defaults to None.
- name (str, optional): Name of the network. Defaults to None.
- auto_assign (bool, optional): If true auto assign addresses. Defaults to True.
-
- Returns:
- Network: Created network
- """
- routes = None
- config = {"private": not public, "noAutoAssignIps": not auto_assign, "routes": routes}
- if target_subnet:
- routes.append({"target": target_subnet, "via": None})
- network = ipaddress.IPv4Network(target_subnet)
- config["ipAssignmentPools"] = [{"ipRangeStart": network[0], "ipRangeEnd": network[-1]}]
-
- if name:
- config.update({"name": name})
-
- data = {"config": config}
- return Network(self._send_request(f"network", data=data, method="post"), self)
-
- def delete_network(self, network_id):
- """Deletes network
-
- Args:
- network_id (str): Network id
- """
- self._send_request(f"network/{network_id}", method="delete", return_json=False)
-
- def get_status(self):
- return self._send_request("status")
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
-
-
-
var session
-
-
-
-Source code
-
@property
-def session(self):
- if not self._session:
- if not self.token:
- raise j.exceptions.Value("Please set token to use the client")
- self._session = requests.Session()
- self._session.headers["Authorization"] = f"Bearer {self.token}"
- return self._session
-
-
-
var token
-
-
getter method this property
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- Returns:
- any: the field value
- """
- # if it's already defined, just return it
- if hasattr(self, inner_name):
- return getattr(self, inner_name)
-
- # if not, it will just return the default value of the field
- # accept raw value as default too
- return field.from_raw(field.default)
def create_network(self, public, target_subnet=None, name=None, auto_assign=True):
- """Create a new network
-
- Args:
- public (bool): Specify if network is public or not
- target_subnet (str, optional): Target network to be pick assignment ips from. Defaults to None.
- name (str, optional): Name of the network. Defaults to None.
- auto_assign (bool, optional): If true auto assign addresses. Defaults to True.
-
- Returns:
- Network: Created network
- """
- routes = None
- config = {"private": not public, "noAutoAssignIps": not auto_assign, "routes": routes}
- if target_subnet:
- routes.append({"target": target_subnet, "via": None})
- network = ipaddress.IPv4Network(target_subnet)
- config["ipAssignmentPools"] = [{"ipRangeStart": network[0], "ipRangeEnd": network[-1]}]
-
- if name:
- config.update({"name": name})
-
- data = {"config": config}
- return Network(self._send_request(f"network", data=data, method="post"), self)
def list_networks(self):
- """List networks available to user
-
- Returns:
- list: All available networks
- """
- return [Network(network, self) for network in self._send_request("network")]
Store defines the interface for the backend storage, let it be filesystem or redis.
-
This module also defines the abstractions needed for any storage backend.
-
Every backend should be able to organize configuration for multiple instance given a location, also
-read/write the config data in raw (string) format.
-
-Source code
-
"""
-Store defines the interface for the backend storage, let it be filesystem or redis.
-
-This module also defines the abstractions needed for any storage backend.
-
-Every backend should be able to organize configuration for multiple instance given a location, also
-read/write the config data in raw (string) format.
-"""
-
-
-import os
-import shutil
-
-import redis
-
-from abc import ABC, abstractmethod
-from enum import Enum
-
-from jumpscale.data.nacl import NACL
-from jumpscale.data.serializers import base64, json
-from jumpscale.core.config import Environment
-from jumpscale.sals.fs import read_file_binary, write_file_binary, rmtree
-
-
-class InvalidPrivateKey(Exception):
- """
- raised when the private key configured is invalid
- """
-
-
-class Location:
- """
- dot-separated auto-location for any type
-
- for example, if we have a class in jumpscale/clients/redis/<type>
- location name will be jumpscale.clients.redis.<type>
- """
-
- def __init__(self, *name_list):
- self.name_list = list(name_list)
-
- @property
- def name(self):
- """
- get dot seprated string from current name list
-
- Returns:
- str: dot separated string
- """
- return ".".join(self.name_list)
-
- @property
- def path(self):
- """
- get a filesystem path with from `name`, where dots are replaced by `os.sep`
-
- Returns:
- str: path
- """
- return os.path.join(*self.name.split("."))
-
- @classmethod
- def from_type(cls, type_):
- """
- get a location from any type/class
-
- Args:
- type_ (type): any type (class)
-
- Returns:
- Location: a location object
- """
- return cls(type_.__module__, type_.__name__)
-
- def __str__(self):
- args = "', '".join(self.name_list)
- cls_name = self.__class__.__name__
- return f"{cls_name}('{args}')"
-
- __repr__ = __str__
-
-
-class EncryptionMode(Enum):
- """
- An enum to select encryption mode based on loading or storing the data
- """
-
- Encrypt = 0
- Decrypt = 1
-
-
-class EncryptionMixin:
- """
- A mixin that provides encrypt and decrypt methods, which can be used in any store
- """
-
- def encrypt(self, data):
- """encrypt data
-
- Args:
- data (str): input string
-
- Returns:
- bytes: encrypted data as byte string
- """
- if not isinstance(data, bytes):
- data = data.encode()
- return self.nacl.encrypt(data, self.public_key)
-
- def decrypt(self, data):
- """decrypt data
-
- Args:
- data (bytes): encrypted byte string
-
- Returns:
- str: decrypted data
- """
- return self.nacl.decrypt(data, self.public_key).decode()
-
-
-class ConfigStore(ABC):
- """
- the interface every config store should implement:
-
- - `read(instance_name)`: reads the data of this instance name
- - `write(instance_name, data)`: writes the data of this instance
- - `list_all(instance_name)`: lists all instance names
- - `delete(instance_name)`: delete instance data
- """
-
- @abstractmethod
- def read(self, instance_name):
- pass
-
- @abstractmethod
- def write(self, instance_name, data):
- pass
-
- @abstractmethod
- def list_all(self):
- pass
-
- @abstractmethod
- def delete(self, instance_name):
- pass
-
-
-class EncryptedConfigStore(ConfigStore, EncryptionMixin):
- """the base class for any config store backend"""
-
- def __init__(self, location):
- self.location = location
- self.config_env = Environment()
- self.priv_key = base64.decode(self.config_env.get_private_key())
- self.nacl = NACL(private_key=self.priv_key)
- self.public_key = self.nacl.public_key.encode()
-
- if not self.priv_key:
- raise InvalidPrivateKey
-
- def _encrypt_value(self, value):
- """
- encrypt a single value
-
- Args:
- value (str): value
-
- Returns:
- str: decrypted value
- """
- return base64.encode(self.encrypt(value)).decode("ascii")
-
- def _decrypt_value(self, value):
- """
- decrypt a single value
-
- Args:
- value (str): value
-
- Returns:
- str: decrypted value
- """
- return self.decrypt(base64.decode(value))
-
- def _process_config(self, config, mode):
- """
- process current config according to encryption mode
-
- Args:
- config (dict): config dict (can be nested)
- mode (EncryptionMode)
- """
- new_config = {}
- for name, value in config.items():
- if name.startswith("__") and value is not None:
- if mode == EncryptionMode.Decrypt:
- new_config[name.lstrip("__")] = self._decrypt_value(value)
- else:
- # preserve __ to know it's an encrypted value
- new_config[name] = self._encrypt_value(value)
- elif isinstance(value, dict):
- new_config[name] = self._process_config(value, mode)
- else:
- new_config[name] = value
- return new_config
-
- def get(self, instance_name):
- """
- get instance config
-
- Args:
- instance_name (str): instance name
-
- Returns:
- dict: instance config as dict
- """
- config = json.loads(self.read(instance_name))
- return self._process_config(config, EncryptionMode.Decrypt)
-
- def save(self, instance_name, config):
- """
- save instance config
-
- Args:
- instance_name (str): name
- config (dict): config data, any key that starts with `__` will be encrypted
-
- Returns:
- bool: written or not
- """
- new_config = self._process_config(config, EncryptionMode.Encrypt)
- return self.write(instance_name, json.dumps(new_config))
-
-
-class FileSystemStore(EncryptedConfigStore):
- """
- Filesystem store is an EncryptedConfigStore
-
- It saves the config relative to `config_env.get_store_config("filesystem")`
-
- To store every instance config in a different path, it uses the given `Location`.
- """
-
- def __init__(self, location):
- """
- create a new `FileSystemStore` that stores config at the given location under configured root.
-
- The root directory can be configured, see `jumpscale.core.config`
-
- Args:
- location (Location): where config will be stored per instance
- """
- super(FileSystemStore, self).__init__(location)
- self.root = self.config_env.get_store_config("filesystem")["path"]
-
- @property
- def config_root(self):
- """
- get the root directory where all configurations are written
-
- Returns:
- str: path
- """
- return os.path.join(self.root, self.location.path)
-
- def get_instance_root(self, instance_name):
- """
- get the directory where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.config_root, instance_name)
-
- def get_path(self, instance_name):
- """
- get the path to data file where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.get_instance_root(instance_name), "data")
-
- def make_path(self, path):
- """
- to ensure the given path, create it if it does not exist
-
- Args:
- path (str): path
- """
- if not os.path.exists(path):
- os.makedirs(os.path.dirname(path), exist_ok=True)
- os.mknod(path)
-
- def read(self, instance_name):
- """
- read config data from the data file
-
- Args:
- instance_name (str): name
-
- Returns:
- str: data
- """
- path = self.get_path(instance_name)
- return read_file_binary(path)
-
- def list_all(self):
- """
- list all instance names (directories under config root)
-
- Returns:
- list: instance/directory names
- """
- if not os.path.exists(self.config_root):
- return []
- return os.listdir(self.config_root)
-
- def write(self, instance_name, data):
- """
- write config data to data file
-
- Args:
- instance_name (str): config
- data (str): data
-
- Returns:
- bool: written or not
- """
- path = self.get_path(instance_name)
- self.make_path(path)
- return write_file_binary(path, data.encode())
-
- def delete(self, instance_name):
- """
- delete instance config directory
-
- Args:
- instance_name (str):
- """
- path = self.get_instance_root(instance_name)
- if os.path.exists(path):
- rmtree(path)
-
-
-class RedisStore(EncryptedConfigStore):
- """
- RedisStore store is an EncryptedConfigStore
-
- It saves the data in redis and configuration for redis comes from `config_env.get_store_config("redis")`
- """
-
- def __init__(self, location):
- """
- create a new redis store, the location given will be used to generate keys
-
- this keys will be combined to get/set instance config
-
- Args:
- location (Location)
- """
- super().__init__(location)
- redis_config = self.config_env.get_store_config("redis")
- self.redis_client = redis.Redis(redis_config["hostname"], redis_config["port"])
-
- def get_key(self, instance_name):
- """
- get a key for an instance
-
- this will return a dot-separated key derived from current location
-
- Args:
- instance_name (str): name
-
- Returns:
- str: key
- """
- return ".".join([self.location.name, instance_name])
-
- def read(self, instance_name):
- """
- read instance config from redis
-
- Args:
- instance_name (name): name
-
- Returns:
- str: data
- """
- return self.redis_client.get(self.get_key(instance_name))
-
- def _full_scan(self, pattern):
- """
- get the full result of a scan command on current redis database by this pattern
-
- Args:
- pattern ([type]): [description]
- """
- keys = []
- cursor, values = self.redis_client.scan(0, pattern)
-
- while values:
- keys += values
- if not cursor:
- break
- cursor, values = self.redis_client.scan(cursor, pattern)
-
- return keys
-
- def get_location_keys(self):
- """
- get all keys under current location (scanned)
-
- Returns:
- list: a list of keys
- """
- return self._full_scan(f"{self.location.name}.*")
-
- def get_instance_keys(self, instance_name):
- """
- get all instance related keys (scanned)
-
- Args:
- instance_name (str): name
-
- Returns:
- list: list of keys
- """
- return self._full_scan(f"{self.location.name}.{instance_name}*")
-
- def list_all(self):
- """
- get all names of instances (instance keys)
-
- Returns:
- [type]: [description]
- """
- names = []
-
- keys = self.get_location_keys()
- for key in keys:
- # remove location name part
- name = key.decode().replace(self.location.name, "").lstrip(".")
- if "." not in name:
- names.append(name)
- return names
-
- def write(self, instance_name, data):
- """
- set data with the corresponding key for this instance
-
- Args:
- instance_name (str): name
- data (str): data
-
- Returns:
- bool: written or not
- """
- return self.redis_client.set(self.get_key(instance_name), data)
-
- def delete(self, instance_name):
- """
- delete all instance related keys
-
- Args:
- instance_name (str): name
-
- Returns:
- bool
- """
- keys = self.get_instance_keys(instance_name)
- if keys:
- return self.redis_client.delete(*keys)
- return True
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class ConfigStore
-(*args, **kwargs)
-
-
-
the interface every config store should implement:
-
-
read(instance_name):
-reads the data of this instance name
-
write(instance_name, data): writes the data of this instance
-
list_all(instance_name): lists all instance names
-
delete(instance_name): delete instance data
-
-
-Source code
-
class ConfigStore(ABC):
- """
- the interface every config store should implement:
-
- - `read(instance_name)`: reads the data of this instance name
- - `write(instance_name, data)`: writes the data of this instance
- - `list_all(instance_name)`: lists all instance names
- - `delete(instance_name)`: delete instance data
- """
-
- @abstractmethod
- def read(self, instance_name):
- pass
-
- @abstractmethod
- def write(self, instance_name, data):
- pass
-
- @abstractmethod
- def list_all(self):
- pass
-
- @abstractmethod
- def delete(self, instance_name):
- pass
config data, any key that starts with __ will be encrypted
-
-
Returns
-
-
bool
-
written or not
-
-
-Source code
-
def save(self, instance_name, config):
- """
- save instance config
-
- Args:
- instance_name (str): name
- config (dict): config data, any key that starts with `__` will be encrypted
-
- Returns:
- bool: written or not
- """
- new_config = self._process_config(config, EncryptionMode.Encrypt)
- return self.write(instance_name, json.dumps(new_config))
A mixin that provides encrypt and decrypt methods, which can be used in any store
-
-Source code
-
class EncryptionMixin:
- """
- A mixin that provides encrypt and decrypt methods, which can be used in any store
- """
-
- def encrypt(self, data):
- """encrypt data
-
- Args:
- data (str): input string
-
- Returns:
- bytes: encrypted data as byte string
- """
- if not isinstance(data, bytes):
- data = data.encode()
- return self.nacl.encrypt(data, self.public_key)
-
- def decrypt(self, data):
- """decrypt data
-
- Args:
- data (bytes): encrypted byte string
-
- Returns:
- str: decrypted data
- """
- return self.nacl.decrypt(data, self.public_key).decode()
class FileSystemStore(EncryptedConfigStore):
- """
- Filesystem store is an EncryptedConfigStore
-
- It saves the config relative to `config_env.get_store_config("filesystem")`
-
- To store every instance config in a different path, it uses the given `Location`.
- """
-
- def __init__(self, location):
- """
- create a new `FileSystemStore` that stores config at the given location under configured root.
-
- The root directory can be configured, see `jumpscale.core.config`
-
- Args:
- location (Location): where config will be stored per instance
- """
- super(FileSystemStore, self).__init__(location)
- self.root = self.config_env.get_store_config("filesystem")["path"]
-
- @property
- def config_root(self):
- """
- get the root directory where all configurations are written
-
- Returns:
- str: path
- """
- return os.path.join(self.root, self.location.path)
-
- def get_instance_root(self, instance_name):
- """
- get the directory where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.config_root, instance_name)
-
- def get_path(self, instance_name):
- """
- get the path to data file where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.get_instance_root(instance_name), "data")
-
- def make_path(self, path):
- """
- to ensure the given path, create it if it does not exist
-
- Args:
- path (str): path
- """
- if not os.path.exists(path):
- os.makedirs(os.path.dirname(path), exist_ok=True)
- os.mknod(path)
-
- def read(self, instance_name):
- """
- read config data from the data file
-
- Args:
- instance_name (str): name
-
- Returns:
- str: data
- """
- path = self.get_path(instance_name)
- return read_file_binary(path)
-
- def list_all(self):
- """
- list all instance names (directories under config root)
-
- Returns:
- list: instance/directory names
- """
- if not os.path.exists(self.config_root):
- return []
- return os.listdir(self.config_root)
-
- def write(self, instance_name, data):
- """
- write config data to data file
-
- Args:
- instance_name (str): config
- data (str): data
-
- Returns:
- bool: written or not
- """
- path = self.get_path(instance_name)
- self.make_path(path)
- return write_file_binary(path, data.encode())
-
- def delete(self, instance_name):
- """
- delete instance config directory
-
- Args:
- instance_name (str):
- """
- path = self.get_instance_root(instance_name)
- if os.path.exists(path):
- rmtree(path)
get the root directory where all configurations are written
-
Returns
-
-
str
-
path
-
-
-Source code
-
@property
-def config_root(self):
- """
- get the root directory where all configurations are written
-
- Returns:
- str: path
- """
- return os.path.join(self.root, self.location.path)
get the directory where instance config is written
-
Args
-
-
instance_name : str
-
name
-
-
Returns
-
-
str
-
path
-
-
-Source code
-
def get_instance_root(self, instance_name):
- """
- get the directory where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.config_root, instance_name)
-
-
-
-def get_path(self, instance_name)
-
-
-
get the path to data file where instance config is written
-
Args
-
-
instance_name : str
-
name
-
-
Returns
-
-
str
-
path
-
-
-Source code
-
def get_path(self, instance_name):
- """
- get the path to data file where instance config is written
-
- Args:
- instance_name (str): name
-
- Returns:
- str: path
- """
- return os.path.join(self.get_instance_root(instance_name), "data")
-
-
-
-def list_all(self)
-
-
-
list all instance names (directories under config root)
-
Returns
-
-
list
-
instance/directory names
-
-
-Source code
-
def list_all(self):
- """
- list all instance names (directories under config root)
-
- Returns:
- list: instance/directory names
- """
- if not os.path.exists(self.config_root):
- return []
- return os.listdir(self.config_root)
-
-
-
-def make_path(self, path)
-
-
-
to ensure the given path, create it if it does not exist
-
Args
-
-
path : str
-
path
-
-
-Source code
-
def make_path(self, path):
- """
- to ensure the given path, create it if it does not exist
-
- Args:
- path (str): path
- """
- if not os.path.exists(path):
- os.makedirs(os.path.dirname(path), exist_ok=True)
- os.mknod(path)
-
-
-
-def read(self, instance_name)
-
-
-
read config data from the data file
-
Args
-
-
instance_name : str
-
name
-
-
Returns
-
-
str
-
data
-
-
-Source code
-
def read(self, instance_name):
- """
- read config data from the data file
-
- Args:
- instance_name (str): name
-
- Returns:
- str: data
- """
- path = self.get_path(instance_name)
- return read_file_binary(path)
-
-
-
-def write(self, instance_name, data)
-
-
-
write config data to data file
-
Args
-
-
instance_name : str
-
config
-
data : str
-
data
-
-
Returns
-
-
bool
-
written or not
-
-
-Source code
-
def write(self, instance_name, data):
- """
- write config data to data file
-
- Args:
- instance_name (str): config
- data (str): data
-
- Returns:
- bool: written or not
- """
- path = self.get_path(instance_name)
- self.make_path(path)
- return write_file_binary(path, data.encode())
class InvalidPrivateKey(Exception):
- """
- raised when the private key configured is invalid
- """
-
-
Ancestors
-
-
builtins.Exception
-
builtins.BaseException
-
-
-
-class Location
-(*name_list)
-
-
-
dot-separated auto-location for any type
-
for example, if we have a class in jumpscale/clients/redis/
-location name will be jumpscale.clients.redis.
-
-Source code
-
class Location:
- """
- dot-separated auto-location for any type
-
- for example, if we have a class in jumpscale/clients/redis/<type>
- location name will be jumpscale.clients.redis.<type>
- """
-
- def __init__(self, *name_list):
- self.name_list = list(name_list)
-
- @property
- def name(self):
- """
- get dot seprated string from current name list
-
- Returns:
- str: dot separated string
- """
- return ".".join(self.name_list)
-
- @property
- def path(self):
- """
- get a filesystem path with from `name`, where dots are replaced by `os.sep`
-
- Returns:
- str: path
- """
- return os.path.join(*self.name.split("."))
-
- @classmethod
- def from_type(cls, type_):
- """
- get a location from any type/class
-
- Args:
- type_ (type): any type (class)
-
- Returns:
- Location: a location object
- """
- return cls(type_.__module__, type_.__name__)
-
- def __str__(self):
- args = "', '".join(self.name_list)
- cls_name = self.__class__.__name__
- return f"{cls_name}('{args}')"
-
- __repr__ = __str__
@classmethod
-def from_type(cls, type_):
- """
- get a location from any type/class
-
- Args:
- type_ (type): any type (class)
-
- Returns:
- Location: a location object
- """
- return cls(type_.__module__, type_.__name__)
-
-
-
-
Instance variables
-
-
var name
-
-
get dot seprated string from current name list
-
Returns
-
-
str
-
dot separated string
-
-
-Source code
-
@property
-def name(self):
- """
- get dot seprated string from current name list
-
- Returns:
- str: dot separated string
- """
- return ".".join(self.name_list)
-
-
-
var path
-
-
get a filesystem path with from name, where dots are replaced by os.sep
-
Returns
-
-
str
-
path
-
-
-Source code
-
@property
-def path(self):
- """
- get a filesystem path with from `name`, where dots are replaced by `os.sep`
-
- Returns:
- str: path
- """
- return os.path.join(*self.name.split("."))
-
-
-
-
-
-class RedisStore
-(location)
-
-
-
RedisStore store is an EncryptedConfigStore
-
It saves the data in redis and configuration for redis comes from config_env.get_store_config("redis")
-
create a new redis store, the location given will be used to generate keys
-
this keys will be combined to get/set instance config
-
Args
-
location (Location)
-
-Source code
-
class RedisStore(EncryptedConfigStore):
- """
- RedisStore store is an EncryptedConfigStore
-
- It saves the data in redis and configuration for redis comes from `config_env.get_store_config("redis")`
- """
-
- def __init__(self, location):
- """
- create a new redis store, the location given will be used to generate keys
-
- this keys will be combined to get/set instance config
-
- Args:
- location (Location)
- """
- super().__init__(location)
- redis_config = self.config_env.get_store_config("redis")
- self.redis_client = redis.Redis(redis_config["hostname"], redis_config["port"])
-
- def get_key(self, instance_name):
- """
- get a key for an instance
-
- this will return a dot-separated key derived from current location
-
- Args:
- instance_name (str): name
-
- Returns:
- str: key
- """
- return ".".join([self.location.name, instance_name])
-
- def read(self, instance_name):
- """
- read instance config from redis
-
- Args:
- instance_name (name): name
-
- Returns:
- str: data
- """
- return self.redis_client.get(self.get_key(instance_name))
-
- def _full_scan(self, pattern):
- """
- get the full result of a scan command on current redis database by this pattern
-
- Args:
- pattern ([type]): [description]
- """
- keys = []
- cursor, values = self.redis_client.scan(0, pattern)
-
- while values:
- keys += values
- if not cursor:
- break
- cursor, values = self.redis_client.scan(cursor, pattern)
-
- return keys
-
- def get_location_keys(self):
- """
- get all keys under current location (scanned)
-
- Returns:
- list: a list of keys
- """
- return self._full_scan(f"{self.location.name}.*")
-
- def get_instance_keys(self, instance_name):
- """
- get all instance related keys (scanned)
-
- Args:
- instance_name (str): name
-
- Returns:
- list: list of keys
- """
- return self._full_scan(f"{self.location.name}.{instance_name}*")
-
- def list_all(self):
- """
- get all names of instances (instance keys)
-
- Returns:
- [type]: [description]
- """
- names = []
-
- keys = self.get_location_keys()
- for key in keys:
- # remove location name part
- name = key.decode().replace(self.location.name, "").lstrip(".")
- if "." not in name:
- names.append(name)
- return names
-
- def write(self, instance_name, data):
- """
- set data with the corresponding key for this instance
-
- Args:
- instance_name (str): name
- data (str): data
-
- Returns:
- bool: written or not
- """
- return self.redis_client.set(self.get_key(instance_name), data)
-
- def delete(self, instance_name):
- """
- delete all instance related keys
-
- Args:
- instance_name (str): name
-
- Returns:
- bool
- """
- keys = self.get_instance_keys(instance_name)
- if keys:
- return self.redis_client.delete(*keys)
- return True
def delete(self, instance_name):
- """
- delete all instance related keys
-
- Args:
- instance_name (str): name
-
- Returns:
- bool
- """
- keys = self.get_instance_keys(instance_name)
- if keys:
- return self.redis_client.delete(*keys)
- return True
-
-
-
-def get_instance_keys(self, instance_name)
-
-
-
get all instance related keys (scanned)
-
Args
-
-
instance_name : str
-
name
-
-
Returns
-
-
list
-
list of keys
-
-
-Source code
-
def get_instance_keys(self, instance_name):
- """
- get all instance related keys (scanned)
-
- Args:
- instance_name (str): name
-
- Returns:
- list: list of keys
- """
- return self._full_scan(f"{self.location.name}.{instance_name}*")
-
-
-
-def get_key(self, instance_name)
-
-
-
get a key for an instance
-
this will return a dot-separated key derived from current location
-
Args
-
-
instance_name : str
-
name
-
-
Returns
-
-
str
-
key
-
-
-Source code
-
def get_key(self, instance_name):
- """
- get a key for an instance
-
- this will return a dot-separated key derived from current location
-
- Args:
- instance_name (str): name
-
- Returns:
- str: key
- """
- return ".".join([self.location.name, instance_name])
-
-
-
-def get_location_keys(self)
-
-
-
get all keys under current location (scanned)
-
Returns
-
-
list
-
a list of keys
-
-
-Source code
-
def get_location_keys(self):
- """
- get all keys under current location (scanned)
-
- Returns:
- list: a list of keys
- """
- return self._full_scan(f"{self.location.name}.*")
-
-
-
-def list_all(self)
-
-
-
get all names of instances (instance keys)
-
Returns
-
-Source code
-
def list_all(self):
- """
- get all names of instances (instance keys)
-
- Returns:
- [type]: [description]
- """
- names = []
-
- keys = self.get_location_keys()
- for key in keys:
- # remove location name part
- name = key.decode().replace(self.location.name, "").lstrip(".")
- if "." not in name:
- names.append(name)
- return names
-
-
-
-def read(self, instance_name)
-
-
-
read instance config from redis
-
Args
-
-
instance_name : name
-
name
-
-
Returns
-
-
str
-
data
-
-
-Source code
-
def read(self, instance_name):
- """
- read instance config from redis
-
- Args:
- instance_name (name): name
-
- Returns:
- str: data
- """
- return self.redis_client.get(self.get_key(instance_name))
-
-
-
-def write(self, instance_name, data)
-
-
-
set data with the corresponding key for this instance
-
Args
-
-
instance_name : str
-
name
-
data : str
-
data
-
-
Returns
-
-
bool
-
written or not
-
-
-Source code
-
def write(self, instance_name, data):
- """
- set data with the corresponding key for this instance
-
- Args:
- instance_name (str): name
- data (str): data
-
- Returns:
- bool: written or not
- """
- return self.redis_client.set(self.get_key(instance_name), data)
def get(key, default=None):
- """ Retrives value from jumpscale config
+ """Retrives value from jumpscale config
Arguments:
key (str): the key you wish to retrieve
@@ -248,7 +252,7 @@
Get/Set
def set(key, val):
- """ Sets value in jumpscale config
+ """Sets value in jumpscale config
Arguments:
key (str): the key you wish to update
@@ -260,7 +264,7 @@
Get/Set
def set_default(key, val):
- """ Sets key to value in jumpscale config and returns
+ """Sets key to value in jumpscale config and returns
Arguments:
key (str): the key you wish to update
@@ -372,7 +376,7 @@
Arguments
Expand source code
def get(key, default=None):
- """ Retrives value from jumpscale config
+ """Retrives value from jumpscale config
Arguments:
key (str): the key you wish to retrieve
@@ -440,7 +444,10 @@
def set(key, val):
- """ Sets value in jumpscale config
+ """Sets value in jumpscale config
Arguments:
key (str): the key you wish to update
@@ -509,7 +517,7 @@
Returns
Expand source code
def set_default(key, val):
- """ Sets key to value in jumpscale config and returns
+ """Sets key to value in jumpscale config and returns
Arguments:
key (str): the key you wish to update
diff --git a/docs/api/jumpscale/core/exceptions.html b/docs/api/jumpscale/core/exceptions.html
deleted file mode 100644
index a11f5ead1..000000000
--- a/docs/api/jumpscale/core/exceptions.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
-jumpscale.core.exceptions API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.core.exceptions
-
-
-
-Source code
-
class JSException(Exception):
- pass
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class JSException
-(*args, **kwargs)
-
-
-
Common base class for all non-exit exceptions.
-
-Source code
-
class JSException(Exception):
- pass
-
-
Ancestors
-
-
builtins.Exception
-
builtins.BaseException
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/core/logging.html b/docs/api/jumpscale/core/logging.html
deleted file mode 100644
index c2767eeb6..000000000
--- a/docs/api/jumpscale/core/logging.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
-jumpscale.core.logging API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.core.logging
-
-
-
-Source code
-
class JSLogger:
- pass
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class JSLogger
-(*args, **kwargs)
-
-
-
-
-Source code
-
class JSLogger:
- pass
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/data/countries/index.html b/docs/api/jumpscale/data/countries/index.html
deleted file mode 100644
index d78689065..000000000
--- a/docs/api/jumpscale/data/countries/index.html
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-jumpscale.data.countries API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.data.countries
-
-
-
This module helps picking a random country or even listing all countries.
Decrypt the message using the private key of the reciever and the sender's public key.
-
Args
-
-
message : bytes
-
The message.
-
private_key : bytes
-
reciever's private key.
-
sender_public_key : bytes
-
sender's public key.
-
-
Returns
-
-
bytes
-
The decryption of the message.
-
-
-Source code
-
def decrypt(message, private_key, sender_public_key):
- """Decrypt the message using the private key of the reciever and the sender's public key.
-
- Args:
- message (bytes): The message.
- private_key (bytes): reciever's private key.
- sender_public_key (bytes): sender's public key.
-
- Returns:
- bytes: The decryption of the message.
- """
- nacl_obj = j.data.nacl.NACL(private_key=private_key)
- message = nacl_obj.decrypt(message, sender_public_key)
- return message
-
-
-
-def decrypt_symmetric(message, symmetric_key)
-
-
-
Decrypt the message using the secret key.
-
Args
-
-
message : bytes
-
The message.
-
symmetric_key : bytes
-
The secret key.
-
-
Returns
-
-
bytes
-
The decryption of the message.
-
-
-Source code
-
def decrypt_symmetric(message, symmetric_key):
- """Decrypt the message using the secret key.
-
- Args:
- message (bytes): The message.
- symmetric_key (bytes): The secret key.
-
- Returns:
- bytes: The decryption of the message.
- """
- nacl_obj = j.data.nacl.NACL(symmetric_key=symmetric_key)
- return nacl_obj.decrypt_symmetric(message, symmetric_key)
Encrypt the message using the public key of the reciever and the sender's private key.
-
Args
-
-
message : bytes
-
The message.
-
private_key : bytes
-
sender's private key.
-
receiver_public_key : bytes
-
receiver's public key.
-
-
Returns
-
-
bytes
-
The encryption of the message.
-
-
-Source code
-
def encrypt(message, private_key, receiver_public_key):
- """Encrypt the message using the public key of the reciever and the sender's private key.
-
- Args:
- message (bytes): The message.
- private_key (bytes): sender's private key.
- receiver_public_key (bytes): receiver's public key.
-
- Returns:
- bytes: The encryption of the message.
- """
- nacl_obj = j.data.nacl.NACL(private_key=private_key)
- message = nacl_obj.encrypt(message, receiver_public_key)
- return message
-
-
-
-def encrypt_symmetric(message, symmetric_key)
-
-
-
Encrypt the message using the secret key.
-
Args
-
-
message : bytes
-
The message.
-
symmetric_key : bytes
-
The secret key.
-
-
Returns
-
-
bytes
-
The encryption of the message.
-
-
-Source code
-
def encrypt_symmetric(message, symmetric_key):
- """Encrypt the message using the secret key.
-
- Args:
- message (bytes): The message.
- symmetric_key (bytes): The secret key.
-
- Returns:
- bytes: The encryption of the message.
- """
- nacl_obj = j.data.nacl.NACL(symmetric_key=symmetric_key)
- return nacl_obj.encrypt_symmetric(message)
def generate_random_name():
- """ Returns a random name "first name" & "last name """
-
- name = "%s_%s" % (choice(right_names), choice(left_names))
-
- return name
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/data/randomnames/index.html b/docs/api/jumpscale/data/randomnames/index.html
deleted file mode 100644
index 9de032bcb..000000000
--- a/docs/api/jumpscale/data/randomnames/index.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-jumpscale.data.randomnames API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
from json import loads as json_loads, dumps as json_dumps
-from pytoml import loads as toml_loads, dumps as toml_dumps
-# from yaml import load as yaml_load, dump as yaml_dump
This is a module with a general tree implementation.
-A sample usage of the Tree class as a file manager
-
if __name__ == "__main__":
- tree = Tree()
- tree.add_node_by_path("root", {"file_name": "root",
- "modified": "12/3/2019"})
- tree.add_node_by_path("etc", {"file_name": "etc",
- "modified": "13/3/2018"})
- tree.add_node_by_path("etc.hosts", {"file_name": "hosts",
- "modified": "14/3/2017"})
- tree.add_node_by_path("etc.passwd", {"file_name": "passwd",
- "modified": "14/3/2016"})
- pred = lambda x: x.data["modified"].split("/")[-1] < "2018"
- too_old = tree.search_custom(pred)
- print("Too old files (before 2018):
-")
- for f in too_old:
- print(f.name + "
-")
- print("Tree before removing /etc/hosts")
- print(tree)
- print("Tree after removing /etc/hosts")
- tree.remove_node_by_path("etc.hosts")
- print(tree)
- passwd_file = tree.get_by_path("etc.passwd")
- passwd_date = passwd_file.data["modified"]
- print("Last time /etc/passwd was modified is: " + passwd_date)
-
-
-Source code
-
"""
-This is a module with a general tree implementation.
-A sample usage of the Tree class as a file manager
-```
-if __name__ == "__main__":
- tree = Tree()
- tree.add_node_by_path("root", {"file_name": "root",
- "modified": "12/3/2019"})
- tree.add_node_by_path("etc", {"file_name": "etc",
- "modified": "13/3/2018"})
- tree.add_node_by_path("etc.hosts", {"file_name": "hosts",
- "modified": "14/3/2017"})
- tree.add_node_by_path("etc.passwd", {"file_name": "passwd",
- "modified": "14/3/2016"})
- pred = lambda x: x.data["modified"].split("/")[-1] < "2018"
- too_old = tree.search_custom(pred)
- print("Too old files (before 2018):\n")
- for f in too_old:
- print(f.name + "\n")
- print("Tree before removing /etc/hosts")
- print(tree)
- print("Tree after removing /etc/hosts")
- tree.remove_node_by_path("etc.hosts")
- print(tree)
- passwd_file = tree.get_by_path("etc.passwd")
- passwd_date = passwd_file.data["modified"]
- print("Last time /etc/passwd was modified is: " + passwd_date)
-```
-"""
-from .exceptions import NameExistsError, EmptyNameError, RootRemoveError
-
-
-class TreeNode:
- def __init__(self, name, parent, data=None):
- """
- name (str) : The name associated with the node
- children (dict[str:TreeNode]): A mapping between names and child nodes
- parent (TreeNode or None) : The parent TreeNode (None for the root)
- data : Data associated with the node
- """
- self.name = name
- self.parent = parent
- self.data = data
- self.children = {}
-
- def add_child(self, node):
- """Adds a new child
-
- Args:
- node (TreeNode): The node to be added
-
- Returns:
- TreeNode: The newly added node
- """
- child_name = node.name
- if child_name in self.children:
- raise NameExistsError("A child with the given name already exists")
- self.children[child_name] = node
- return node
-
- def search_by_name(self, name):
- """Search in the node's subtree for nodes with the given name
-
- Args:
- name (str): The name to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.name == name)
-
- def search_by_data(self, data):
- """Search in the node's subtree for nodes with the given data
-
- Args:
- data: The data to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.data == data)
-
- def search_custom(self, func):
- """Search the node's subtree the nodes satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- result = []
- for v in self.children.values():
- result.extend(v.search_custom(func))
-
- if self.name != "" and func(self):
- result.append(self)
- return result
-
- def get_child_by_name(self, name):
- """Get the child with the given name
-
- Args:
- name (str): The name of the child
-
- Returns:
- TreeNode: The reqiested child. None if it doesn't exist.
- """
- return self.children.get(name)
-
- def remove_child(self, node):
- """Remove the node from the children if it exists
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node
- """
- return self.remove_child_by_name(node.name)
-
- def remove_child_by_name(self, name):
- """Remove the node from the children
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node. None if it doesn't exist
- """
- if name in self.children:
- node = self.children[name]
- del self.children[name]
- return node
-
- def get_path(self):
- """Retrieves the path of the node
-
- Returns:
- str: The path
- """
- if self.name == "":
- return ""
- parent_path = self.parent.get_path()
- if parent_path == "":
- return self.name
- else:
- return parent_path + "." + self.name
-
- def __str__(self, indentation=0):
- """Returns a string representing the node's subtree
-
- Args:
- indentation (int, optional): The level to which the representation\
- will be indented. Defaults to 0.
-
- Returns:
- str: The tree representation
- """
- result = "\t" * indentation + self._string_repr() + "\n"
- for v in self.children.values():
- result += v.__str__(indentation + 1)
- return result
-
- def _string_repr(self):
- """A helper function to return the node's name and data as a string
-
- Returns:
- str: The node's string representation
- """
- if self.name == "":
- return "dummy_root"
- else:
- return self.name + str(self.data).replace("\n", "\\n")
-
-
-class Tree:
- """"
- A class to represent a tree
- """
-
- def __init__(self):
- self.root = TreeNode("", None)
-
- def search_by_data(self, data):
- """Search the nodes in the tree with the given data
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_data(data)
-
- def search_by_name(self, name):
- """Search the nodes in the tree with the passed name
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_name(name)
-
- def search_custom(self, func):
- """Search the nodes in the tree satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_custom(func)
-
- def get_by_path(self, path):
- """Retrieves a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Returns:
- None if an intermidiate node is not found.\
- Else the searched node is returned
- """
- path_arr = path.split(".")
- current_node = self.root
- for name in path_arr:
- next_node = current_node.get_child_by_name(name)
- if next_node is None:
- return None
- current_node = next_node
- return current_node
-
- def remove_node(self, node):
- """Remove a node from the tree.
-
- Args:
- node (TreeNode): The node to be removed
- """
- if node == self.root:
- raise RootRemoveError("Can't remove the root node")
- node.parent.remove_child(node)
- return node
-
- def add_node_by_path(self, path, data=None):
- """Add a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Notes:
- If intermidiate nodes are not found while traversing the path,\
- they are created with data=None.
- """
- path_arr = path.split(".")
- current_node = self.root
- for path_name in path_arr[:-1]:
- if path_name == "":
- raise EmptyNameError("Nodes with empty names are not allowed")
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- next_node = TreeNode(path_name, current_node)
- current_node.add_child(next_node)
- current_node = next_node
- new_node = TreeNode(path_arr[-1], current_node, data)
- return current_node.add_child(new_node)
-
- def remove_node_by_path(self, path):
- """Remove a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
- """
- path_arr = path.split(".")
- current_node = self.root
- parent_node = None
- for path_name in path_arr:
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- return None
- parent_node = current_node
- current_node = next_node
- return parent_node.remove_child(current_node)
-
- def __str__(self):
- "Return a string representation of the tree"
- return self.root.__str__(0)
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class Tree
-
-
-
"
-A class to represent a tree
-
-Source code
-
class Tree:
- """"
- A class to represent a tree
- """
-
- def __init__(self):
- self.root = TreeNode("", None)
-
- def search_by_data(self, data):
- """Search the nodes in the tree with the given data
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_data(data)
-
- def search_by_name(self, name):
- """Search the nodes in the tree with the passed name
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_name(name)
-
- def search_custom(self, func):
- """Search the nodes in the tree satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_custom(func)
-
- def get_by_path(self, path):
- """Retrieves a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Returns:
- None if an intermidiate node is not found.\
- Else the searched node is returned
- """
- path_arr = path.split(".")
- current_node = self.root
- for name in path_arr:
- next_node = current_node.get_child_by_name(name)
- if next_node is None:
- return None
- current_node = next_node
- return current_node
-
- def remove_node(self, node):
- """Remove a node from the tree.
-
- Args:
- node (TreeNode): The node to be removed
- """
- if node == self.root:
- raise RootRemoveError("Can't remove the root node")
- node.parent.remove_child(node)
- return node
-
- def add_node_by_path(self, path, data=None):
- """Add a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Notes:
- If intermidiate nodes are not found while traversing the path,\
- they are created with data=None.
- """
- path_arr = path.split(".")
- current_node = self.root
- for path_name in path_arr[:-1]:
- if path_name == "":
- raise EmptyNameError("Nodes with empty names are not allowed")
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- next_node = TreeNode(path_name, current_node)
- current_node.add_child(next_node)
- current_node = next_node
- new_node = TreeNode(path_arr[-1], current_node, data)
- return current_node.add_child(new_node)
-
- def remove_node_by_path(self, path):
- """Remove a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
- """
- path_arr = path.split(".")
- current_node = self.root
- parent_node = None
- for path_name in path_arr:
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- return None
- parent_node = current_node
- current_node = next_node
- return parent_node.remove_child(current_node)
-
- def __str__(self):
- "Return a string representation of the tree"
- return self.root.__str__(0)
-
-
Methods
-
-
-def add_node_by_path(self, path, data=None)
-
-
-
Add a node designated by the given path
-
Args
-
-
path : str
-
A string of names separated by a '.' that reaches
-the desired node when followed
-
data
-
The data associated with the newly added node
-
-
Notes
-
If intermidiate nodes are not found while traversing the path,
-they are created with data=None.
-
-Source code
-
def add_node_by_path(self, path, data=None):
- """Add a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Notes:
- If intermidiate nodes are not found while traversing the path,\
- they are created with data=None.
- """
- path_arr = path.split(".")
- current_node = self.root
- for path_name in path_arr[:-1]:
- if path_name == "":
- raise EmptyNameError("Nodes with empty names are not allowed")
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- next_node = TreeNode(path_name, current_node)
- current_node.add_child(next_node)
- current_node = next_node
- new_node = TreeNode(path_arr[-1], current_node, data)
- return current_node.add_child(new_node)
-
-
-
-def get_by_path(self, path)
-
-
-
Retrieves a node designated by the given path
-
Args
-
-
path : str
-
A string of names separated by a '.' that reaches
-the desired node when followed
def get_by_path(self, path):
- """Retrieves a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
-
- data: The data associated with the newly added node
-
- Returns:
- None if an intermidiate node is not found.\
- Else the searched node is returned
- """
- path_arr = path.split(".")
- current_node = self.root
- for name in path_arr:
- next_node = current_node.get_child_by_name(name)
- if next_node is None:
- return None
- current_node = next_node
- return current_node
def remove_node(self, node):
- """Remove a node from the tree.
-
- Args:
- node (TreeNode): The node to be removed
- """
- if node == self.root:
- raise RootRemoveError("Can't remove the root node")
- node.parent.remove_child(node)
- return node
-
-
-
-def remove_node_by_path(self, path)
-
-
-
Remove a node designated by the given path
-
Args
-
-
path : str
-
A string of names separated by a '.' that reaches
-the desired node when followed
-
-
-Source code
-
def remove_node_by_path(self, path):
- """Remove a node designated by the given path
-
- Args:
- path (str): A string of names separated by a '.' that reaches\
- the desired node when followed
- """
- path_arr = path.split(".")
- current_node = self.root
- parent_node = None
- for path_name in path_arr:
- next_node = current_node.get_child_by_name(path_name)
- if next_node is None:
- return None
- parent_node = current_node
- current_node = next_node
- return parent_node.remove_child(current_node)
def search_by_data(self, data):
- """Search the nodes in the tree with the given data
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_data(data)
def search_by_name(self, name):
- """Search the nodes in the tree with the passed name
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_by_name(name)
-
-
-
-def search_custom(self, func)
-
-
-
Search the nodes in the tree satisfying the given predicate
def search_custom(self, func):
- """Search the nodes in the tree satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- return self.root.search_custom(func)
-
-
-
-
-
-class TreeNode
-(name, parent, data=None)
-
-
-
name
-(str)
-: The name associated with the node
-children (dict[str:TreeNode]): A mapping between names and child nodes
-parent
-(TreeNode or None)
-: The parent TreeNode (None for the root)
-data
-: Data associated with the node
-
-Source code
-
class TreeNode:
- def __init__(self, name, parent, data=None):
- """
- name (str) : The name associated with the node
- children (dict[str:TreeNode]): A mapping between names and child nodes
- parent (TreeNode or None) : The parent TreeNode (None for the root)
- data : Data associated with the node
- """
- self.name = name
- self.parent = parent
- self.data = data
- self.children = {}
-
- def add_child(self, node):
- """Adds a new child
-
- Args:
- node (TreeNode): The node to be added
-
- Returns:
- TreeNode: The newly added node
- """
- child_name = node.name
- if child_name in self.children:
- raise NameExistsError("A child with the given name already exists")
- self.children[child_name] = node
- return node
-
- def search_by_name(self, name):
- """Search in the node's subtree for nodes with the given name
-
- Args:
- name (str): The name to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.name == name)
-
- def search_by_data(self, data):
- """Search in the node's subtree for nodes with the given data
-
- Args:
- data: The data to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.data == data)
-
- def search_custom(self, func):
- """Search the node's subtree the nodes satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- result = []
- for v in self.children.values():
- result.extend(v.search_custom(func))
-
- if self.name != "" and func(self):
- result.append(self)
- return result
-
- def get_child_by_name(self, name):
- """Get the child with the given name
-
- Args:
- name (str): The name of the child
-
- Returns:
- TreeNode: The reqiested child. None if it doesn't exist.
- """
- return self.children.get(name)
-
- def remove_child(self, node):
- """Remove the node from the children if it exists
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node
- """
- return self.remove_child_by_name(node.name)
-
- def remove_child_by_name(self, name):
- """Remove the node from the children
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node. None if it doesn't exist
- """
- if name in self.children:
- node = self.children[name]
- del self.children[name]
- return node
-
- def get_path(self):
- """Retrieves the path of the node
-
- Returns:
- str: The path
- """
- if self.name == "":
- return ""
- parent_path = self.parent.get_path()
- if parent_path == "":
- return self.name
- else:
- return parent_path + "." + self.name
-
- def __str__(self, indentation=0):
- """Returns a string representing the node's subtree
-
- Args:
- indentation (int, optional): The level to which the representation\
- will be indented. Defaults to 0.
-
- Returns:
- str: The tree representation
- """
- result = "\t" * indentation + self._string_repr() + "\n"
- for v in self.children.values():
- result += v.__str__(indentation + 1)
- return result
-
- def _string_repr(self):
- """A helper function to return the node's name and data as a string
-
- Returns:
- str: The node's string representation
- """
- if self.name == "":
- return "dummy_root"
- else:
- return self.name + str(self.data).replace("\n", "\\n")
def add_child(self, node):
- """Adds a new child
-
- Args:
- node (TreeNode): The node to be added
-
- Returns:
- TreeNode: The newly added node
- """
- child_name = node.name
- if child_name in self.children:
- raise NameExistsError("A child with the given name already exists")
- self.children[child_name] = node
- return node
def get_child_by_name(self, name):
- """Get the child with the given name
-
- Args:
- name (str): The name of the child
-
- Returns:
- TreeNode: The reqiested child. None if it doesn't exist.
- """
- return self.children.get(name)
-
-
-
-def get_path(self)
-
-
-
Retrieves the path of the node
-
Returns
-
-
str
-
The path
-
-
-Source code
-
def get_path(self):
- """Retrieves the path of the node
-
- Returns:
- str: The path
- """
- if self.name == "":
- return ""
- parent_path = self.parent.get_path()
- if parent_path == "":
- return self.name
- else:
- return parent_path + "." + self.name
def remove_child(self, node):
- """Remove the node from the children if it exists
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node
- """
- return self.remove_child_by_name(node.name)
def remove_child_by_name(self, name):
- """Remove the node from the children
-
- Args:
- node (TreeNode): The node to be deleted
-
- Returns:
- TreeNode: The deleted node. None if it doesn't exist
- """
- if name in self.children:
- node = self.children[name]
- del self.children[name]
- return node
-
-
-
-def search_by_data(self, data)
-
-
-
Search in the node's subtree for nodes with the given data
def search_by_data(self, data):
- """Search in the node's subtree for nodes with the given data
-
- Args:
- data: The data to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.data == data)
-
-
-
-def search_by_name(self, name)
-
-
-
Search in the node's subtree for nodes with the given name
def search_by_name(self, name):
- """Search in the node's subtree for nodes with the given name
-
- Args:
- name (str): The name to be searched for
-
- Returns:
- list of TreeNode: The found nodes
- """
- return self.search_custom(lambda x: x.name == name)
-
-
-
-def search_custom(self, func)
-
-
-
Search the node's subtree the nodes satisfying the given predicate
def search_custom(self, func):
- """Search the node's subtree the nodes satisfying the given predicate
-
- Args:
- func (function): A predicate the recieves a TreeNode
-
- Returns:
- list of TreeNode: The nodes found
- """
- result = []
- for v in self.children.values():
- result.extend(v.search_custom(func))
-
- if self.name != "" and func(self):
- result.append(self)
- return result
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/entry_points/index.html b/docs/api/jumpscale/entry_points/index.html
index 17a7e0e7e..ab9747db7 100644
--- a/docs/api/jumpscale/entry_points/index.html
+++ b/docs/api/jumpscale/entry_points/index.html
@@ -41,10 +41,6 @@
import os
-import re
-import time
-import sys
-import traceback
-import argparse
-import requests
-
-import inspect
-import cgi
-
-from prompt_toolkit import PromptSession
-from prompt_toolkit.completion import Completion
-from prompt_toolkit.shortcuts import print_formatted_text
-from prompt_toolkit.eventloop.async_generator import AsyncGeneratorItem
-from prompt_toolkit.validation import Validator, ValidationError
-from prompt_toolkit.styles import Style
-from prompt_toolkit.formatted_text import HTML
-from jumpscale import threesdk
-from jumpscale.threesdk import settings
-from jumpscale.core.exceptions.exceptions import JSException
-from jumpscale.clients.docker.docker import DockerClient
-from jumpscale.threesdk.threebot import ThreeBot, DEFAULT_IMAGE
-from jumpscale.core.config import get_current_version
-
-
-BASE_CONFIG_DIR = os.path.join(os.environ.get("HOME", "/root"), ".jsng")
-HISTORY_FILENAME = os.path.join(BASE_CONFIG_DIR, "history.txt")
-
-DEFAULT_TOOLBAR_MSG = "Welcome to 3sdk enter info for help"
-
-style = Style.from_dict(
- {
- # User input (default text).
- "bottom-toolbar": "#ffffff bg:#333333",
- "default": "#aaaaaa",
- # Prompt.
- }
-)
-
-
-def get_binary_link():
- resp = requests.get("https://api.github.com/repos/threefoldtech/js-ng/releases/latest")
- resp = resp.json()
- # get versions
- download_link = ""
- version = resp["tag_name"]
- for platform in resp["assets"]:
- if sys.platform in platform["name"]:
- download_link = platform["browser_download_url"]
- return version, download_link
-
-
-def update():
- print("checking for updates")
- latest_version, binary_link = get_binary_link()
- current_version = get_current_version()
- if latest_version != current_version:
- print(f"version: {latest_version} is available get it from {binary_link}")
- return
- docker_client = DockerClient()
- print("Checking for new docker image")
- docker_client.client.images.pull(f"{DEFAULT_IMAGE}:{latest_version}")
- print("Starting 3sdk containers")
- for container_name in os.listdir(os.path.expanduser("~/.config/jumpscale/containers")):
- ThreeBot.delete(container_name)
- ThreeBot.install(container_name)
-
-
-def print_error(error):
- print_formatted_text(HTML("<ansired>{}</ansired>".format(cgi.html.escape(str(error)))))
-
-
-def partition_line(line):
- def replacer(m):
- return m.group().replace(" ", "\0").strip("\"'")
-
- result = re.sub(r"""(['"]).*?\1""", replacer, line)
- parts = []
- for part in result.split():
- parts.append(part.replace("\0", " "))
- return parts
-
-
-def noexpert_error(error):
- reports_location = f"{os.environ.get('HOME', os.environ.get('USERPROFILE', ''))}/sandbox/reports"
- error_file_location = f"{reports_location}/jsngreport_{time.strftime('%d%H%M%S')}.log"
- if not os.path.exists(reports_location):
- os.makedirs(reports_location)
- with open(error_file_location, "w") as f:
- f.write(str(error))
- err_msg = f"""Something went wrong. Please contact support at https://support.grid.tf/
-Error report file has been created on your machine in this location: {error_file_location}
- """
- return err_msg
-
-
-class Shell(Validator):
- def __init__(self):
- self._prompt = PromptSession()
- self.mode = None
- self.toolbarmsg = DEFAULT_TOOLBAR_MSG
-
- def get_completions_async(self, document, complete_event):
- text = document.current_line_before_cursor
- parts = partition_line(text)
- if not parts:
- root = None
- more = []
- else:
- root, more = parts[0], parts[1:]
- items = []
- if not root or not hasattr(threesdk, root):
- style = "bg:ansibrightblue"
- items += threesdk.__all__
- self.toolbarmsg = DEFAULT_TOOLBAR_MSG
- else:
- style = "bg:ansigreen"
- obj = getattr(threesdk, root)
- if not more or not hasattr(obj, more[0]):
- # complete object attributes
- self.toolbarmsg = threesdk._get_doc_line(obj.__doc__)
- for name, member in inspect.getmembers(obj, inspect.isroutine):
- if not name.startswith("_"):
- items.append(name)
- text = "" if not more else more[-1]
- else:
- # complete arguments
- func = getattr(obj, more[0])
- self.toolbarmsg = threesdk._get_doc_line(func.__doc__)
- style = "bg:ansired"
- for arg in inspect.getfullargspec(func).args:
- field = arg + "="
- if field in text:
- continue
- items.append(field)
- if len(more) > 1:
- text = more[-1]
- else:
- text = ""
-
- for item in items:
- if not item:
- continue
- if isinstance(item, Completion):
- item.start_position = -len(text)
- else:
- item = Completion(item, -len(text))
- regex = ".*".join(text)
- item.style = style
- if not text or re.search(regex, item.text):
- yield AsyncGeneratorItem(item)
-
- def bottom_toolbar(self):
- return [("class:bottom-toolbar", self.toolbarmsg)]
-
- def validate(self, document):
- text = document.current_line_before_cursor
- if not text:
- return
- root, *more = text.split(" ")
- submodule = getattr(threesdk, root, None)
- if not submodule:
- raise ValidationError(message=f"No such subcommand {root}")
- if not more and callable(submodule):
- func = root
- elif more:
- func = getattr(submodule, more[0], None)
- if not func:
- raise ValidationError(message=f"{root} has no command called {more[0]}")
- else:
- raise ValidationError(message="Invalid command")
- # TODO: validate args
- return
-
- def get_func_kwargs(self, cmd):
- parts = partition_line(cmd)
- root, extra = parts[0], parts[1:]
- module = getattr(threesdk, root)
- if inspect.isroutine(module):
- return module, self.get_kwargs(module, *extra)
- else:
- func = getattr(module, extra[0])
- return func, self.get_kwargs(func, *extra[1:])
-
- def get_kwargs(self, func, *args):
- funcspec = inspect.getfullargspec(func)
- kwargs = {}
- for arg in args:
- key, val = arg.split("=", 1)
- isbool = funcspec.annotations.get(key) is bool
- if isbool:
- if val:
- val = val.lower() in ["y", "yes", "1", "true"]
- else:
- val = True
- kwargs[key] = val
- return kwargs
-
- def execute(self, cmd):
- if not cmd.strip():
- return
- try:
- func, kwargs = self.get_func_kwargs(cmd)
- func(**kwargs)
- except JSException as e:
- if not settings.expert:
- print_error(str(e))
- else:
- print_error(traceback.format_exc())
- except Exception:
- if not settings.expert:
- print_error(noexpert_error(traceback.format_exc()))
- else:
- print_error(traceback.format_exc())
-
- def make_prompt(self):
- root = ("class:default", "3sdk>")
- while True:
- try:
- result = self.prompt([root])
- self.execute(result)
- except (EOFError, KeyboardInterrupt):
- sys.exit(0)
-
- def prompt(self, msg):
- return self._prompt.prompt(
- msg, completer=self, validator=self, style=style, bottom_toolbar=self.bottom_toolbar,
- )
-
-
-def run():
- parser = argparse.ArgumentParser()
- parser.add_argument("--update", action="store_true", help="Update 3sdk")
- parser.add_argument("--expert", action="store_true", help="Run 3sdk in expert mode")
- args = parser.parse_args()
- settings.expert = args.expert
-
- if args.update:
- update()
- else:
- shell = Shell()
- shell.make_prompt()
-
-
-if __name__ == "__main__":
- run()
-
-
-
-
-
-
-
-
Functions
-
-
-def get_binary_link()
-
-
-
-
-
-Expand source code
-
-
def get_binary_link():
- resp = requests.get("https://api.github.com/repos/threefoldtech/js-ng/releases/latest")
- resp = resp.json()
- # get versions
- download_link = ""
- version = resp["tag_name"]
- for platform in resp["assets"]:
- if sys.platform in platform["name"]:
- download_link = platform["browser_download_url"]
- return version, download_link
-
-
-
-def noexpert_error(error)
-
-
-
-
-
-Expand source code
-
-
def noexpert_error(error):
- reports_location = f"{os.environ.get('HOME', os.environ.get('USERPROFILE', ''))}/sandbox/reports"
- error_file_location = f"{reports_location}/jsngreport_{time.strftime('%d%H%M%S')}.log"
- if not os.path.exists(reports_location):
- os.makedirs(reports_location)
- with open(error_file_location, "w") as f:
- f.write(str(error))
- err_msg = f"""Something went wrong. Please contact support at https://support.grid.tf/
-Error report file has been created on your machine in this location: {error_file_location}
- """
- return err_msg
-
-
-
-def partition_line(line)
-
-
-
-
-
-Expand source code
-
-
def partition_line(line):
- def replacer(m):
- return m.group().replace(" ", "\0").strip("\"'")
-
- result = re.sub(r"""(['"]).*?\1""", replacer, line)
- parts = []
- for part in result.split():
- parts.append(part.replace("\0", " "))
- return parts
def get_completions_async(self, document, complete_event):
- text = document.current_line_before_cursor
- parts = partition_line(text)
- if not parts:
- root = None
- more = []
- else:
- root, more = parts[0], parts[1:]
- items = []
- if not root or not hasattr(threesdk, root):
- style = "bg:ansibrightblue"
- items += threesdk.__all__
- self.toolbarmsg = DEFAULT_TOOLBAR_MSG
- else:
- style = "bg:ansigreen"
- obj = getattr(threesdk, root)
- if not more or not hasattr(obj, more[0]):
- # complete object attributes
- self.toolbarmsg = threesdk._get_doc_line(obj.__doc__)
- for name, member in inspect.getmembers(obj, inspect.isroutine):
- if not name.startswith("_"):
- items.append(name)
- text = "" if not more else more[-1]
- else:
- # complete arguments
- func = getattr(obj, more[0])
- self.toolbarmsg = threesdk._get_doc_line(func.__doc__)
- style = "bg:ansired"
- for arg in inspect.getfullargspec(func).args:
- field = arg + "="
- if field in text:
- continue
- items.append(field)
- if len(more) > 1:
- text = more[-1]
- else:
- text = ""
-
- for item in items:
- if not item:
- continue
- if isinstance(item, Completion):
- item.start_position = -len(text)
- else:
- item = Completion(item, -len(text))
- regex = ".*".join(text)
- item.style = style
- if not text or re.search(regex, item.text):
- yield AsyncGeneratorItem(item)
"""
-#TODO docs for fs.
-
-"""
-
-import pathlib
-import tempfile
-import os
-import shutil
-import stat
-from distutils import dir_util
-from typing import List
-
-basename = os.path.basename
-dirname = os.path.dirname
-common_path = os.path.commonpath
-common_prefix = os.path.commonprefix
-norm_path = os.path.normpath
-norm_case = os.path.normcase
-get_access_time = os.path.getatime
-get_modified_time = os.path.getmtime
-get_creation_time = os.path.getctime
-sep = os.path.sep
-is_samefile = os.path.samefile
-expandvars = os.path.expandvars
-expanduser = os.path.expanduser
-realpath = os.path.realpath
-
-
-def home():
- return str(pathlib.Path.home())
-
-
-def cwd():
- """Return current working directory.
-
- Returns:
- str: current directory.
- """
- return str(pathlib.Path.cwd())
-
-
-def is_dir(path: str) -> bool:
- """Checks if path is a dir
-
- :param path: path to check
- :type path: str
- :return: True if is dir else False
- :rtype: bool
- """
- return pathlib.Path(path).is_dir()
-
-
-def is_file(path: str) -> bool:
- """Checks if path is a file
-
- Args:
- path (str): path to check if is file
-
- Returns:
- bool: True if is file and False otherwise
- """
- return pathlib.Path(path).is_file()
-
-
-def is_symlink(path: str) -> bool:
- """Checks if path symlink
-
- Args:
- path (str): path to check if symlink
-
- Returns:
- bool: True if symlink False otherwise
- """
- return pathlib.Path(path).is_symlink()
-
-
-def is_absolute(path: str) -> bool:
- """Checks if path is absolute
-
- Returns:
- bool: True if absolute
- """
- return pathlib.Path(path).is_absolute()
-
-
-def is_mount(path: str) -> bool:
- """Checks if path is mount
-
- Returns:
- bool: True if mount
- """
- return pathlib.Path(path).is_mount()
-
-
-def is_ascii_file(path: str, checksize=4096) -> bool:
- """Checks if file `path` is ascii
-
- Args:
- path (str): file path
- checksize (int, optional): checksize. Defaults to 4096.
-
- Returns:
- bool: True if ascii file
- """
- # TODO: let's talk about checksize feature.
- try:
- with open(path, encoding="ascii") as f:
- f.read()
- return True
- except UnicodeDecodeError:
- return False
-
-
-def is_empty_dir(path: str) -> bool:
- """Checks if path is emptry directory
-
- Args:
- path (str): path to check if empty directory
-
- Returns:
- bool: True if path is emptry directory
- """
-
- try:
- g = pathlib.Path(path).iterdir()
- next(g)
- except StopIteration:
- # means we can't get next entry -> dir is empty.
- return True
- else:
- return False
-
-
-is_binary_file = lambda path: not is_ascii_file(path)
-
-
-def is_broken_link(path: str, clean=False) -> bool:
- """Checks if path is a broken symlink
-
- Args:
- path (str): path to check
- clean (bool, optional): remove symlink if broken. Defaults to False.
-
- Raises:
- NotImplementedError: [description]
-
- Returns:
- bool: True if path is a broken symlink
- """
- raise NotImplementedError()
-
-
-def stem(path: str) -> str:
- """returns the stem of a path (path without parent directory and without extension)
- e.g
- In [2]: t = j.sals.fs.stem("/tmp/tmp-5383p1GOmMOOwvfi.tpl")
-
- In [3]: t
- Out[3]: 'tmp-5383p1GOmMOOwvfi'
-
- Args:
- path (str): path we want to get its stem
-
- Returns:
- [type]: [description]
- """
- return pathlib.Path(path).stem
-
-
-def mkdir(path: str, exist_ok=True):
- """Makes directory at path
-
- Args:
- path (str): path to create dir at
- exist_ok (bool, optional): won't fail if directory exists. Defaults to True.
-
- Returns:
- [type]: [description]
- """
- return pathlib.Path(path).mkdir(exist_ok=exist_ok)
-
-
-def mkdirs(path: str, exist_ok=True):
- """Creates dir as well as all non exisitng parents in the path
-
- Args:
- path (str): path to create dir at
- exist_ok (bool, optional): won't fail if directory exists. Defaults to True.
- """
- return os.makedirs(path, exist_ok=exist_ok)
-
-
-def parent(path: str) -> str:
- """Get path's parent
-
- Args:
- path (str): path to get its parent
-
- Returns:
- str: parent path.
- """
- return str(pathlib.Path(path).parent)
-
-
-def parents(path: str) -> List[str]:
- """Get parents list
-
- e.g
- >>> j.sals.fs.parents("/tmp/home/ahmed/myfile.py")
- [PosixPath('/tmp/home/ahmed'),
- PosixPath('/tmp/home'),
- PosixPath('/tmp'),
- PosixPath('/')]
-
- Args:
- path (str): path to get its parents
-
- Returns:
- List[str]: list of parents
- """
-
- return list([str(p) for p in pathlib.Path(path).parents])
-
-
-def path_parts(path: str) -> List[str]:
- """Convert path to a list of parts
- e.g
- '/tmp/tmp-5383p1GOmMOOwvfi.tpl' -> ('/', 'tmp', 'tmp-5383p1GOmMOOwvfi.tpl')
- Args:
- path (str): path to convert to parts
-
- Returns:
- List[str]: path parts.
- """
- return pathlib.Path(path).parts
-
-
-def exists(path: str) -> bool:
- """Checks if path exists
-
- Args:
- path (str): path to check for existence
-
- Returns:
- bool: True if exists
- """
- return pathlib.Path(path).exists()
-
-
-def rename(path1: str, path2: str):
- """Rename path1 to path2
-
- Args:
- path1 (str): source path
- path2 (str): dest path
-
- """
- return pathlib.Path(path1).rename(path2)
-
-
-def expanduser(path: str) -> str:
- """Expands the tilde `~` to username
- e.g
- j.sals.fs.expanduser("~/work") -> '/home/xmonader/work'
- Args:
- path (str): path with optionally `~`
-
- Returns:
- str: path with tilde `~` resolved.
- """
- return str(pathlib.Path(path).expanduser())
-
-
-def unlink(path: str):
- """unlink path
-
- Args:
- path (str): path to unlink
-
-
- """
- return pathlib.Path(path).unlink()
-
-
-def read_text(path: str) -> str:
- """read ascii content at `path`
-
- Args:
- path (str): ascii file path
-
- Returns:
- str: ascii content in path
- """
- return pathlib.Path(path).read_text()
-
-
-read_ascii = read_file = read_text
-
-
-def read_bytes(path: str) -> bytes:
- """read binary content at `path`
-
- Args:
- path (str): binary file path
-
- Returns:
- bytes: binary content in path
- """
- return pathlib.Path(path).read_bytes()
-
-
-read_binary = read_file_binary = read_bytes
-
-
-def write_text(path: str, data: str, encoding=None):
- """write text `data` to path `path` with encoding
-
- Args:
- path (str): path to write to
- data (str): ascii content
- encoding ([type], optional): encoding. Defaults to None.
-
-
- """
- return pathlib.Path(path).write_text(data, encoding)
-
-
-write_ascii = write_file = write_text
-
-
-def write_bytes(path: str, data: bytes):
- """write binary `data` to path `path`
-
- Args:
- path (str): path to write to
- data (bytes): binary content
-
- """
- return pathlib.Path(path).write_bytes(data)
-
-
-write_binary = write_file_binary = write_bytes
-
-
-def touch(path: str):
- """create file
-
- Args:
- path (str): path to create file
-
- """
- return pathlib.Path(path).touch()
-
-
-def get_temp_filename(mode="w+b", buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None) -> str:
- """Get temp filename
-
- Args:
- mode (str, optional): [description]. Defaults to "w+b".
- buffering (int, optional): buffering. Defaults to -1.
- encoding ([type], optional): encoding . Defaults to None.
- newline ([type], optional): Defaults to None.
- suffix ([type], optional): ending suffix. Defaults to None.
- prefix ([type], optional): prefix . Defaults to None.
- dir ([type], optional): where to create the file. Defaults to None.
-
- Returns:
- [str]: temp filename
- """
- return tempfile.NamedTemporaryFile(mode, buffering, encoding, newline, suffix, prefix, dir).name
-
-
-def get_temp_dirname(suffix=None, prefix=None, dir=None) -> str:
- """Get temp directory name
-
- Args:
- suffix ([type], optional): ending suffix. Defaults to None.
- prefix ([type], optional): prefix . Defaults to None.
- dir ([type], optional): where to create the directory. Defaults to None.
-
-
- Returns:
- str: temp directory name.
- """
- return tempfile.TemporaryDirectory(suffix, prefix, dir).name
-
-
-NamedTemporaryFile = tempfile.NamedTemporaryFile
-TempraryDirectory = tempfile.TemporaryDirectory
-mkdtemp = tempfile.mkdtemp
-mkstemp = tempfile.mkstemp
-get_temp_dir = tempfile.gettempdir
-
-
-def parts_to_path(parts: List[str]) -> str:
- """Convert list of path parts into a path string
-
- Args:
- parts (List[str]): path parts
-
- Returns:
- str: joined path parts
- """
- path = pathlib.Path(parts[0])
- for p in parts[1:]:
- path = path.joinpath(p)
- return str(path)
-
-
-def join_paths(*paths):
- return parts_to_path(paths)
-
-
-def rm_emptry_dir(path: str):
- """Remove empty directory
-
- Args:
- path (str): path to remove.
- """
- path = pathlib.Path(path)
- path.rmdir()
-
-
-def rmtree(path: str):
- """Remove directory tree
- Args:
- path (str): path to remove
- """
- path = pathlib.Path(path)
- if path.is_file() or path.is_symlink():
- os.remove(path)
- elif path.is_dir():
- shutil.rmtree(path)
-
-
-def copy_stat(src: str, dst: str, times=True, perms=True):
- """Copy stat of src to dst
-
- Args:
- src (str): source path
- dst (str): destination
- times (bool, optional): Defaults to True.
- perms (bool, optional): permissions Defaults to True.
- """
- st = os.stat(src)
- if hasattr(os, "utime"):
- os.utime(dst, (st.st_atime, st.st_mtime))
- if hasattr(os, "chmod"):
- m = stat.S_IMODE(st.st_mode)
- os.chmod(dst, m)
-
-
-def copy_file(src: str, dst: str, times=False, perms=False):
- """Copy the file, optionally copying the permission bits (mode) and
- last access/modify time. If the destination file exists, it will be
- replaced. Raises OSError if the destination is a directory. If the
- platform does not have the ability to set the permission or times,
- ignore it.
- This is shutil.copyfile plus bits of shutil.copymode and
- shutil.copystat's implementation.
- shutil.copy and shutil.copy2 are not supported but are easy to do.
-
- Args:
- src (str): source path
- dst (str): destination
-
- """
- shutil.copyfile(src, dst)
- if times or perms:
- copy_stat(src, dst, times, perms)
-
-
-def symlink(src: str, dst: str, overwrite=False):
- """Create a symbolic link.
-
- Args:
- src (str): Source of link
- dst (str): Destination path of link
- overwrite (bool, optional): If link exists will delete it. Defaults to False.
- """
- if overwrite and exists(dst):
- os.unlink(dst)
-
- os.symlink(src, dst)
-
-
-copy_tree = dir_util.copy_tree
-chdir = os.chdir
-
-
-def change_dir(path: str) -> str:
- """Change current working directory to `path`
-
- Args:
- path (str): path to switch current working directory to
-
- Returns:
- str: new current working dir
- """
- os.chdir(path)
- return path
-
-
-def chmod(path: str, mode):
- """change file mode for path to mode
-
- Args:
- path (str): path
- mode (int): file mode
-
- """
- return pathlib.Path(path).chmod(mode)
-
-
-def lchmod(path: str, mode):
- """change file mode for path to mode (handles links too)
-
- Args:
- path (str): path
- mode (int): file mode
-
- """
- return pathlib.Path(path).lchmod(mode)
-
-
-def stat(path: str):
- """Gets stat of path `path`
-
- Args:
- path (str): path to get its stat
-
- Returns:
- stat_result: returns stat struct.
- """
-
- return pathlib.Path(path).stat()
-
-
-def lstat(path: str):
- """Gets stat of path `path` (handles links)
-
- Args:
- path (str): path to get its stat
-
- Returns:
- stat_result: returns stat struct.
- """
-
- return pathlib.Path(path).lstat()
-
-
-def resolve(path: str) -> str:
- """resolve `.` and `..` in path
-
- Args:
- path (str): path with optionally `.` and `..`
-
- Returns:
- str: resolved path
- """
- return pathlib.Path(path).resolve()
-
-
-def extension(path: str, include_dot=True):
- """Gets the extension of path
- '/home/ahmed/myfile.py' -> `.py` if include_dot else `py`
-
- Args:
- path (str): [description]
- include_dot (bool, optional): controls whether to include the dot or not. Defaults to True.
-
- Returns:
- str: extension
- """
- splitted = os.path.splitext(path)
- ext = ""
- if len(splitted) == 1:
- return ext
-
- if include_dot:
- return splitted[1]
- else:
- return splitted[1].strip(".")
-
-
-ext = extension
-
-
-def chown():
- raise NotImplementedError()
-
-
-def read_link(path):
- raise NotImplementedError()
-
-
-def remove_links(path):
- raise NotImplementedError()
-
-
-def change_filenames(from_, to, where):
- pass
-
-
-def replace_words_in_files(from_, to, where):
- pass
-
-
-move = shutil.move
-
-
-def default_filter_fun(entry):
- return True
-
-
-def walk(path: str, pat="*", filter_fun=default_filter_fun):
- """walk recursively on path
- e.g
- for el in walk('/tmp', filter_fun=j.sals.fs.is_file) : ..
- for el in walk('/tmp', filter_fun=j.sals.fs.is_dir) : ..
- for el in walk('/tmp', filter_fun= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
-
- Args:
- path (str): path to walk over
- pat (str, optional): pattern to match against. Defaults to "*".
- filter_fun (Function, optional): filtering function. Defaults to default_filter_fun which accepts anything.
- """
- p = pathlib.Path(path)
- for entry in p.rglob(pat):
- # use rglob instead of glob("**/*")
- if filter_fun(entry):
- yield str(entry)
-
-
-def walk_non_recursive(path: str, filter_fun=default_filter_fun):
- """walks non recursively on path
- e.g
- for el in walk('/tmp', filter=j.sals.fs.is_file) : ..
- for el in walk('/tmp', filter=j.sals.fs.is_dir) : ..
- for el in walk('/tmp', filter= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
-
- Args:
- path (str): path to walk over
- pat (str, optional): pattern to match against. Defaults to "*".
- filter_fun (Function, optional): filtering function. Defaults to default_filter_fun which accepts anything.
- """
- p = pathlib.Path(path)
- for entry in p.iterdir():
- if filter_fun(entry):
- yield str(entry)
-
-
-def walk_files(path: str, recursive=True):
- """
- walk over files in path and applies function `fun`
- e.g
-
- for el in walk_files('/tmp') : ..
-
- Args:
- path (str): path to walk over
- recursive (bool, optional): recursive or not. Defaults to True.
-
-
- """
-
- if recursive:
- return walk(path, filter_fun=is_file)
- else:
- return walk_non_recursive(path, filter_fun=is_file)
-
-
-def walk_dirs(path, recursive=True):
- """
- walk over directories in path and applies function `fun`
- e.g
-
- for el in walk_dirs('/tmp') : ..
-
-
- Args:
- path (str): path to walk over
- recursive (bool, optional): recursive or not. Defaults to True.
-
-
- """
- if recursive:
- return walk(path, filter_fun=is_dir)
- else:
- return walk_non_recursive(path, filter_fun=is_dir)
-
-
-
-
-
-
-
-
Functions
-
-
-def change_dir(path)
-
-
-
Change current working directory to path
-
Args
-
-
path : str
-
path to switch current working directory to
-
-
Returns
-
-
str
-
new current working dir
-
-
-Source code
-
def change_dir(path: str) -> str:
- """Change current working directory to `path`
-
- Args:
- path (str): path to switch current working directory to
-
- Returns:
- str: new current working dir
- """
- os.chdir(path)
- return path
Copy the file, optionally copying the permission bits (mode) and
-last access/modify time. If the destination file exists, it will be
-replaced. Raises OSError if the destination is a directory. If the
-platform does not have the ability to set the permission or times,
-ignore it.
-This is shutil.copyfile plus bits of shutil.copymode and
-shutil.copystat's implementation.
-shutil.copy and shutil.copy2 are not supported but are easy to do.
-
Args
-
-
src : str
-
source path
-
dst : str
-
destination
-
-
-Source code
-
def copy_file(src: str, dst: str, times=False, perms=False):
- """Copy the file, optionally copying the permission bits (mode) and
- last access/modify time. If the destination file exists, it will be
- replaced. Raises OSError if the destination is a directory. If the
- platform does not have the ability to set the permission or times,
- ignore it.
- This is shutil.copyfile plus bits of shutil.copymode and
- shutil.copystat's implementation.
- shutil.copy and shutil.copy2 are not supported but are easy to do.
-
- Args:
- src (str): source path
- dst (str): destination
-
- """
- shutil.copyfile(src, dst)
- if times or perms:
- copy_stat(src, dst, times, perms)
def get_temp_filename(mode="w+b", buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None) -> str:
- """Get temp filename
-
- Args:
- mode (str, optional): [description]. Defaults to "w+b".
- buffering (int, optional): buffering. Defaults to -1.
- encoding ([type], optional): encoding . Defaults to None.
- newline ([type], optional): Defaults to None.
- suffix ([type], optional): ending suffix. Defaults to None.
- prefix ([type], optional): prefix . Defaults to None.
- dir ([type], optional): where to create the file. Defaults to None.
-
- Returns:
- [str]: temp filename
- """
- return tempfile.NamedTemporaryFile(mode, buffering, encoding, newline, suffix, prefix, dir).name
-
-
-
-def home()
-
-
-
-
-Source code
-
def home():
- return str(pathlib.Path.home())
-
-
-
-def is_absolute(path)
-
-
-
Checks if path is absolute
-
Returns
-
-
bool
-
True if absolute
-
-
-Source code
-
def is_absolute(path: str) -> bool:
- """Checks if path is absolute
-
- Returns:
- bool: True if absolute
- """
- return pathlib.Path(path).is_absolute()
-
-
-
-def is_ascii_file(path, checksize=4096)
-
-
-
Checks if file path is ascii
-
Args
-
-
path : str
-
file path
-
checksize : int, optional
-
checksize. Defaults to 4096.
-
-
Returns
-
-
bool
-
True if ascii file
-
-
-Source code
-
def is_ascii_file(path: str, checksize=4096) -> bool:
- """Checks if file `path` is ascii
-
- Args:
- path (str): file path
- checksize (int, optional): checksize. Defaults to 4096.
-
- Returns:
- bool: True if ascii file
- """
- # TODO: let's talk about checksize feature.
- try:
- with open(path, encoding="ascii") as f:
- f.read()
- return True
- except UnicodeDecodeError:
- return False
-
-
-
-def is_binary_file(path)
-
-
-
-
-Source code
-
is_binary_file = lambda path: not is_ascii_file(path)
-
-
-
-def is_broken_link(path, clean=False)
-
-
-
Checks if path is a broken symlink
-
Args
-
-
path : str
-
path to check
-
clean : bool, optional
-
remove symlink if broken. Defaults to False.
-
-
Raises
-
-
NotImplementedError
-
[description]
-
-
Returns
-
-
bool
-
True if path is a broken symlink
-
-
-Source code
-
def is_broken_link(path: str, clean=False) -> bool:
- """Checks if path is a broken symlink
-
- Args:
- path (str): path to check
- clean (bool, optional): remove symlink if broken. Defaults to False.
-
- Raises:
- NotImplementedError: [description]
-
- Returns:
- bool: True if path is a broken symlink
- """
- raise NotImplementedError()
-
-
-
-def is_dir(path)
-
-
-
Checks if path is a dir
-
:param path: path to check
-:type path: str
-:return: True if is dir else False
-:rtype: bool
-
-Source code
-
def is_dir(path: str) -> bool:
- """Checks if path is a dir
-
- :param path: path to check
- :type path: str
- :return: True if is dir else False
- :rtype: bool
- """
- return pathlib.Path(path).is_dir()
-
-
-
-def is_empty_dir(path)
-
-
-
Checks if path is emptry directory
-
Args
-
-
path : str
-
path to check if empty directory
-
-
Returns
-
-
bool
-
True if path is emptry directory
-
-
-Source code
-
def is_empty_dir(path: str) -> bool:
- """Checks if path is emptry directory
-
- Args:
- path (str): path to check if empty directory
-
- Returns:
- bool: True if path is emptry directory
- """
-
- try:
- g = pathlib.Path(path).iterdir()
- next(g)
- except StopIteration:
- # means we can't get next entry -> dir is empty.
- return True
- else:
- return False
-
-
-
-def is_file(path)
-
-
-
Checks if path is a file
-
Args
-
-
path : str
-
path to check if is file
-
-
Returns
-
-
bool
-
True if is file and False otherwise
-
-
-Source code
-
def is_file(path: str) -> bool:
- """Checks if path is a file
-
- Args:
- path (str): path to check if is file
-
- Returns:
- bool: True if is file and False otherwise
- """
- return pathlib.Path(path).is_file()
-
-
-
-def is_mount(path)
-
-
-
Checks if path is mount
-
Returns
-
-
bool
-
True if mount
-
-
-Source code
-
def is_mount(path: str) -> bool:
- """Checks if path is mount
-
- Returns:
- bool: True if mount
- """
- return pathlib.Path(path).is_mount()
-
-
-
-def is_symlink(path)
-
-
-
Checks if path symlink
-
Args
-
-
path : str
-
path to check if symlink
-
-
Returns
-
-
bool
-
True if symlink False otherwise
-
-
-Source code
-
def is_symlink(path: str) -> bool:
- """Checks if path symlink
-
- Args:
- path (str): path to check if symlink
-
- Returns:
- bool: True if symlink False otherwise
- """
- return pathlib.Path(path).is_symlink()
def lstat(path: str):
- """Gets stat of path `path` (handles links)
-
- Args:
- path (str): path to get its stat
-
- Returns:
- stat_result: returns stat struct.
- """
-
- return pathlib.Path(path).lstat()
-
-
-
-def mkdir(path, exist_ok=True)
-
-
-
Makes directory at path
-
Args
-
-
path : str
-
path to create dir at
-
exist_ok : bool, optional
-
won't fail if directory exists. Defaults to True.
-
-
Returns
-
-Source code
-
def mkdir(path: str, exist_ok=True):
- """Makes directory at path
-
- Args:
- path (str): path to create dir at
- exist_ok (bool, optional): won't fail if directory exists. Defaults to True.
-
- Returns:
- [type]: [description]
- """
- return pathlib.Path(path).mkdir(exist_ok=exist_ok)
-
-
-
-def mkdirs(path, exist_ok=True)
-
-
-
Creates dir as well as all non exisitng parents in the path
-
Args
-
-
path : str
-
path to create dir at
-
exist_ok : bool, optional
-
won't fail if directory exists. Defaults to True.
-
-
-Source code
-
def mkdirs(path: str, exist_ok=True):
- """Creates dir as well as all non exisitng parents in the path
-
- Args:
- path (str): path to create dir at
- exist_ok (bool, optional): won't fail if directory exists. Defaults to True.
- """
- return os.makedirs(path, exist_ok=exist_ok)
def parents(path: str) -> List[str]:
- """Get parents list
-
- e.g
- >>> j.sals.fs.parents("/tmp/home/ahmed/myfile.py")
- [PosixPath('/tmp/home/ahmed'),
- PosixPath('/tmp/home'),
- PosixPath('/tmp'),
- PosixPath('/')]
-
- Args:
- path (str): path to get its parents
-
- Returns:
- List[str]: list of parents
- """
-
- return list([str(p) for p in pathlib.Path(path).parents])
-
-
-
-def parts_to_path(parts)
-
-
-
Convert list of path parts into a path string
-
Args
-
-
parts : List[str]
-
path parts
-
-
Returns
-
-
str
-
joined path parts
-
-
-Source code
-
def parts_to_path(parts: List[str]) -> str:
- """Convert list of path parts into a path string
-
- Args:
- parts (List[str]): path parts
-
- Returns:
- str: joined path parts
- """
- path = pathlib.Path(parts[0])
- for p in parts[1:]:
- path = path.joinpath(p)
- return str(path)
-
-
-
-def path_parts(path)
-
-
-
Convert path to a list of parts
-e.g
-'/tmp/tmp-5383p1GOmMOOwvfi.tpl' ->
-('/', 'tmp', 'tmp-5383p1GOmMOOwvfi.tpl')
-
Args
-
-
path : str
-
path to convert to parts
-
-
Returns
-
List[str]: path parts.
-
-Source code
-
def path_parts(path: str) -> List[str]:
- """Convert path to a list of parts
- e.g
- '/tmp/tmp-5383p1GOmMOOwvfi.tpl' -> ('/', 'tmp', 'tmp-5383p1GOmMOOwvfi.tpl')
- Args:
- path (str): path to convert to parts
-
- Returns:
- List[str]: path parts.
- """
- return pathlib.Path(path).parts
def rmtree(path: str):
- """Remove directory tree
- Args:
- path (str): path to remove
- """
- path = pathlib.Path(path)
- if path.is_file() or path.is_symlink():
- os.remove(path)
- elif path.is_dir():
- shutil.rmtree(path)
-
-
-
-def stat(path)
-
-
-
Gets stat of path path
-
Args
-
-
path : str
-
path to get its stat
-
-
Returns
-
-
stat_result
-
returns stat struct.
-
-
-Source code
-
def stat(path: str):
- """Gets stat of path `path`
-
- Args:
- path (str): path to get its stat
-
- Returns:
- stat_result: returns stat struct.
- """
-
- return pathlib.Path(path).stat()
-
-
-
-def stem(path)
-
-
-
returns the stem of a path (path without parent directory and without extension)
-e.g
-In [2]: t = j.sals.fs.stem("/tmp/tmp-5383p1GOmMOOwvfi.tpl")
-
In [3]: t
-Out[3]: 'tmp-5383p1GOmMOOwvfi'
-
-
Args
-
-
path : str
-
path we want to get its stem
-
-
Returns
-
-Source code
-
def stem(path: str) -> str:
- """returns the stem of a path (path without parent directory and without extension)
- e.g
- In [2]: t = j.sals.fs.stem("/tmp/tmp-5383p1GOmMOOwvfi.tpl")
-
- In [3]: t
- Out[3]: 'tmp-5383p1GOmMOOwvfi'
-
- Args:
- path (str): path we want to get its stem
-
- Returns:
- [type]: [description]
- """
- return pathlib.Path(path).stem
-
-
-
-def symlink(src, dst, overwrite=False)
-
-
-
Create a symbolic link.
-
Args
-
-
src : str
-
Source of link
-
dst : str
-
Destination path of link
-
overwrite : bool, optional
-
If link exists will delete it. Defaults to False.
-
-
-Source code
-
def symlink(src: str, dst: str, overwrite=False):
- """Create a symbolic link.
-
- Args:
- src (str): Source of link
- dst (str): Destination path of link
- overwrite (bool, optional): If link exists will delete it. Defaults to False.
- """
- if overwrite and exists(dst):
- os.unlink(dst)
-
- os.symlink(src, dst)
walk recursively on path
-e.g
-for el in walk('/tmp', filter_fun=j.sals.fs.is_file) : ..
-for el in walk('/tmp', filter_fun=j.sals.fs.is_dir) : ..
-for el in walk('/tmp', filter_fun= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
Args
-
-
path : str
-
path to walk over
-
pat : str, optional
-
pattern to match against. Defaults to "*".
-
filter_fun : Function, optional
-
filtering function. Defaults to default_filter_fun which accepts anything.
-
-
-Source code
-
def walk(path: str, pat="*", filter_fun=default_filter_fun):
- """walk recursively on path
- e.g
- for el in walk('/tmp', filter_fun=j.sals.fs.is_file) : ..
- for el in walk('/tmp', filter_fun=j.sals.fs.is_dir) : ..
- for el in walk('/tmp', filter_fun= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
-
- Args:
- path (str): path to walk over
- pat (str, optional): pattern to match against. Defaults to "*".
- filter_fun (Function, optional): filtering function. Defaults to default_filter_fun which accepts anything.
- """
- p = pathlib.Path(path)
- for entry in p.rglob(pat):
- # use rglob instead of glob("**/*")
- if filter_fun(entry):
- yield str(entry)
-
-
-
-def walk_dirs(path, recursive=True)
-
-
-
walk over directories in path and applies function fun
-e.g
-
for el in walk_dirs('/tmp') : ..
-
-
Args
-
-
path : str
-
path to walk over
-
recursive : bool, optional
-
recursive or not. Defaults to True.
-
-
-Source code
-
def walk_dirs(path, recursive=True):
- """
- walk over directories in path and applies function `fun`
- e.g
-
- for el in walk_dirs('/tmp') : ..
-
-
- Args:
- path (str): path to walk over
- recursive (bool, optional): recursive or not. Defaults to True.
-
-
- """
- if recursive:
- return walk(path, filter_fun=is_dir)
- else:
- return walk_non_recursive(path, filter_fun=is_dir)
-
-
-
-def walk_files(path, recursive=True)
-
-
-
walk over files in path and applies function fun
-e.g
-
for el in walk_files('/tmp') : ..
-
-
Args
-
-
path : str
-
path to walk over
-
recursive : bool, optional
-
recursive or not. Defaults to True.
-
-
-Source code
-
def walk_files(path: str, recursive=True):
- """
- walk over files in path and applies function `fun`
- e.g
-
- for el in walk_files('/tmp') : ..
-
- Args:
- path (str): path to walk over
- recursive (bool, optional): recursive or not. Defaults to True.
-
-
- """
-
- if recursive:
- return walk(path, filter_fun=is_file)
- else:
- return walk_non_recursive(path, filter_fun=is_file)
walks non recursively on path
-e.g
-for el in walk('/tmp', filter=j.sals.fs.is_file) : ..
-for el in walk('/tmp', filter=j.sals.fs.is_dir) : ..
-for el in walk('/tmp', filter= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
Args
-
-
path : str
-
path to walk over
-
pat : str, optional
-
pattern to match against. Defaults to "*".
-
filter_fun : Function, optional
-
filtering function. Defaults to default_filter_fun which accepts anything.
-
-
-Source code
-
def walk_non_recursive(path: str, filter_fun=default_filter_fun):
- """walks non recursively on path
- e.g
- for el in walk('/tmp', filter=j.sals.fs.is_file) : ..
- for el in walk('/tmp', filter=j.sals.fs.is_dir) : ..
- for el in walk('/tmp', filter= lambda x: len(x)>4 and (j.sals.fs.is_file(x) or j.sals.fs.is_dir(x)) ) : ..
-
-
- Args:
- path (str): path to walk over
- pat (str, optional): pattern to match against. Defaults to "*".
- filter_fun (Function, optional): filtering function. Defaults to default_filter_fun which accepts anything.
- """
- p = pathlib.Path(path)
- for entry in p.iterdir():
- if filter_fun(entry):
- yield str(entry)
-
-
-
-def write_ascii(path, data, encoding=None)
-
-
-
write text data to path path with encoding
-
Args
-
-
path : str
-
path to write to
-
data : str
-
ascii content
-
encoding : [type], optional
-
encoding. Defaults to None.
-
-
-Source code
-
def write_text(path: str, data: str, encoding=None):
- """write text `data` to path `path` with encoding
-
- Args:
- path (str): path to write to
- data (str): ascii content
- encoding ([type], optional): encoding. Defaults to None.
-
-
- """
- return pathlib.Path(path).write_text(data, encoding)
-
-
-
-def write_binary(path, data)
-
-
-
write binary data to path path
-
Args
-
-
path : str
-
path to write to
-
data : bytes
-
binary content
-
-
-Source code
-
def write_bytes(path: str, data: bytes):
- """write binary `data` to path `path`
-
- Args:
- path (str): path to write to
- data (bytes): binary content
-
- """
- return pathlib.Path(path).write_bytes(data)
-
-
-
-def write_bytes(path, data)
-
-
-
write binary data to path path
-
Args
-
-
path : str
-
path to write to
-
data : bytes
-
binary content
-
-
-Source code
-
def write_bytes(path: str, data: bytes):
- """write binary `data` to path `path`
-
- Args:
- path (str): path to write to
- data (bytes): binary content
-
- """
- return pathlib.Path(path).write_bytes(data)
-
-
-
-def write_file(path, data, encoding=None)
-
-
-
write text data to path path with encoding
-
Args
-
-
path : str
-
path to write to
-
data : str
-
ascii content
-
encoding : [type], optional
-
encoding. Defaults to None.
-
-
-Source code
-
def write_text(path: str, data: str, encoding=None):
- """write text `data` to path `path` with encoding
-
- Args:
- path (str): path to write to
- data (str): ascii content
- encoding ([type], optional): encoding. Defaults to None.
-
-
- """
- return pathlib.Path(path).write_text(data, encoding)
-
-
-
-def write_file_binary(path, data)
-
-
-
write binary data to path path
-
Args
-
-
path : str
-
path to write to
-
data : bytes
-
binary content
-
-
-Source code
-
def write_bytes(path: str, data: bytes):
- """write binary `data` to path `path`
-
- Args:
- path (str): path to write to
- data (bytes): binary content
-
- """
- return pathlib.Path(path).write_bytes(data)
-
-
-
-def write_text(path, data, encoding=None)
-
-
-
write text data to path path with encoding
-
Args
-
-
path : str
-
path to write to
-
data : str
-
ascii content
-
encoding : [type], optional
-
encoding. Defaults to None.
-
-
-Source code
-
def write_text(path: str, data: str, encoding=None):
- """write text `data` to path `path` with encoding
-
- Args:
- path (str): path to write to
- data (str): ascii content
- encoding ([type], optional): encoding. Defaults to None.
-
-
- """
- return pathlib.Path(path).write_text(data, encoding)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/sals/fs/fs2.html b/docs/api/jumpscale/sals/fs/fs2.html
deleted file mode 100644
index dc307ae5c..000000000
--- a/docs/api/jumpscale/sals/fs/fs2.html
+++ /dev/null
@@ -1,1030 +0,0 @@
-
-
-
-
-
-
-jumpscale.sals.fs.fs2 API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.sals.fs.fs2
-
-
-
-Source code
-
import pathlib
-import tempfile
-import os
-import shutil
-import stat
-from distutils import dir_util
-
-def home():
- return str(pathlib.Path.home())
-
-
-def cwd():
- return str(pathlib.Path.cwd())
-
-
-basename = os.path.basename
-dirname = os.path.dirname
-common_path = os.path.commonpath
-common_prefix = os.path.commonprefix
-norm_path = os.path.normpath
-norm_case = os.path.normcase
-get_access_time = os.path.getatime
-get_modified_time = os.path.getmtime
-get_creation_time = os.path.getctime
-sep = os.path.sep
-is_samefile = os.path.samefile
-expandvars = os.path.expandvars
-expanduser = os.path.expanduser
-
-def is_dir(path):
- return pathlib.Path(path).is_dir()
-
-def is_file(path):
- return pathlib.Path(path).is_file()
-
-
-def is_symlink(path):
- return pathlib.Path(path).is_symlink()
-
-
-def is_absolute(path):
- return pathlib.Path(path).is_absolute()
-
-
-def is_mount(path):
- return pathlib.Path(path).is_mount()
-
-
-def is_ascii_file(filename, checksize=4096):
- # TODO: let's talk about checksize feature.
- try:
- with open(filename, encoding="ascii") as f:
- f.read()
- return True
- except UnicodeDecodeError:
- return False
-
-
-def is_empty_dir(path):
- try:
- g = pathlib.Path(path).iterdir()
- next(g)
- except StopIteration:
- # means we can't get next entry -> dir is empty.
- return True
- else:
- return False
-
-
-is_binary_file = lambda path: not is_ascii_file(path)
-
-
-def is_broken_link(path, clean=False):
- raise NotImplementedError()
-
-
-def stem(path):
- return pathlib.Path(path).stem
-
-
-def mkdir(path, exist_ok=True):
- return pathlib.Path(path).mkdir(exist_ok=exist_ok)
-
-
-def parent(path):
- return pathlib.Path(path).parent
-
-
-def parents(path):
- """
- [PosixPath('/tmp/home/ahmed'),
- PosixPath('/tmp/home'),
- PosixPath('/tmp'),
- PosixPath('/')]
- """
- return list(pathlib.Path(path).parnets)
-
-
-def path_parts(path):
- return pathlib.Path(path).parts
-
-
-def exists(path):
- return pathlib.Path(path).exists()
-
-
-def rename(path1, path2):
- return pathlib.Path(path1).rename(path2)
-
-
-def expanduser(path):
- return pathlib.Path(path).expanduser()
-
-
-def unlink(path):
- return pathlib.Path(path).unlink()
-
-
-def read_text(path):
- return pathlib.Path(path).read_text()
-
-
-read_ascii = read_file = read_text
-
-
-def read_bytes(path):
- return pathlib.Path(path).read_bytes()
-
-
-read_binary = read_file_binary = read_bytes
-
-
-def write_text(path, data, encoding=None):
- return pathlib.Path(path).write_text(data, encoding)
-
-
-write_ascii = write_file = write_text
-
-
-def write_bytes(path, data):
- return pathlib.Path(path).write_bytes(data)
-
-write_binary = write_file_binary = write_bytes
-
-def touch(path):
- return pathlib.Path(path).touch()
-
-
-def get_temp_filename(mode="w+b", buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None):
- return tempfile.NamedTemporaryFile(mode, buffering, encoding, newline, suffix, prefix, dir).name
-
-
-def get_temp_dirname(suffix=None, prefix=None, dir=None):
- return tempfile.TemporaryDirectory(suffix, prefix, dir).name
-
-
-NamedTemporaryFile = tempfile.NamedTemporaryFile
-TempraryDirectory = tempfile.TemporaryDirectory
-mkdtemp = tempfile.mkdtemp
-mkstemp = tempfile.mkstemp
-get_temp_dir = tempfile.gettempdir
-
-def parts_to_path(parts):
- path = pathlib.Path(parts[0])
- for p in parts[1:]:
- path.joinpath(p)
-
-def rm_emptry_dir(path):
- path = pathlib.Path(path)
- path.rmdir()
-
-
-def rmtree(path):
- path = pathlib.Path(path)
- if path.is_file() or path.is_link():
- os.remove(path)
- elif path.is_dir():
- shutil.rmtree(path)
- if not parents:
- return
- p = path.parent
- while p:
- try:
- os.rmdir(p)
- except os.error:
- break
- p = p.parent
-
-
-def copy_stat(src, dst, times=True, perms=True):
- st = os.stat(src)
- if hasattr(os, 'utime'):
- os.utime(dst, (st.st_atime, st.st_mtime))
- if hasattr(os, 'chmod'):
- m = stat.S_IMODE(st.st_mode)
- os.chmod(dst, m)
-
-def copy_file(src, dst, times=False, perms=False):
- """Copy the file, optionally copying the permission bits (mode) and
- last access/modify time. If the destination file exists, it will be
- replaced. Raises OSError if the destination is a directory. If the
- platform does not have the ability to set the permission or times,
- ignore it.
- This is shutil.copyfile plus bits of shutil.copymode and
- shutil.copystat's implementation.
- shutil.copy and shutil.copy2 are not supported but are easy to do.
- """
- shutil.copyfile(src, dst)
- if times or perms:
- copy_stat(src, dst, times, perms)
-
-def copy_stat(src, dst, times=True, perms=True):
- st = os.stat(src)
- if hasattr(os, 'utime'):
- os.utime(dst, (st.st_atime, st.st_mtime))
- if hasattr(os, 'chmod'):
- m = stat.S_IMODE(st.st_mode)
- os.chmod(dst, m)
-
-copy_tree = dir_util.copy_tree
-chdir = os.chdir
-
-def change_dir(to):
- os.chdir(path)
- return cwd()
-
-
-def chmod(path, mode):
- return pathlib.Path(path).chmod(mode)
-
-def lchmod(path, mode):
- return pathlib.Path(path).lchmod(mode)
-
-
-def stat(path):
- return pathlib.Path(path).stat()
-
-
-def lstat(path):
- return pathlib.Path(path).lstat()
-
-
-def resolve(path):
- return pathlib.Path(path).resolve()
-
-
-def extension(path, include_dot=True):
- splitted = os.path.splitext(path)
- ext = ""
- if len(splitted) == 1:
- return ext
-
- if include_dot:
- return splitted[1]
- else:
- return splitted[1].strip(".")
-
-def chown():
- raise NotImplementedError()
-
-def read_link(path):
- raise NotImplementedError()
-
-def remove_links(path):
- raise NotImplementedError()
-
-
-def change_filenames(from_, to, where):
- pass
-
-def replace_words_in_files(from_, to, where):
- pass
-
-move = shutil.move
Copy the file, optionally copying the permission bits (mode) and
-last access/modify time. If the destination file exists, it will be
-replaced. Raises OSError if the destination is a directory. If the
-platform does not have the ability to set the permission or times,
-ignore it.
-This is shutil.copyfile plus bits of shutil.copymode and
-shutil.copystat's implementation.
-shutil.copy and shutil.copy2 are not supported but are easy to do.
-
-Source code
-
def copy_file(src, dst, times=False, perms=False):
- """Copy the file, optionally copying the permission bits (mode) and
- last access/modify time. If the destination file exists, it will be
- replaced. Raises OSError if the destination is a directory. If the
- platform does not have the ability to set the permission or times,
- ignore it.
- This is shutil.copyfile plus bits of shutil.copymode and
- shutil.copystat's implementation.
- shutil.copy and shutil.copy2 are not supported but are easy to do.
- """
- shutil.copyfile(src, dst)
- if times or perms:
- copy_stat(src, dst, times, perms)
def is_empty_dir(path):
- try:
- g = pathlib.Path(path).iterdir()
- next(g)
- except StopIteration:
- # means we can't get next entry -> dir is empty.
- return True
- else:
- return False
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/sals/hostsfile/hostsfile.html b/docs/api/jumpscale/sals/hostsfile/hostsfile.html
deleted file mode 100644
index f802177b8..000000000
--- a/docs/api/jumpscale/sals/hostsfile/hostsfile.html
+++ /dev/null
@@ -1,363 +0,0 @@
-
-
-
-
-
-
-jumpscale.sals.hostsfile.hostsfile API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.sals.hostsfile.hostsfile
-
-
-
-Source code
-
import re
-
-
-class HostsFile:
- def __init__(self, hosts_file_path):
- self.path = hosts_file_path
- self.content = self._parse()
-
- def _parse(self):
- with open(self.path, "r") as file:
- content_text = file.read()
- content_lines = content_text.splitlines()
- ip_lines = []
- regex = r"""\d+\.\d+\.\d+\.\d+"""
- for line in content_lines:
- if re.search(regex, line):
- ip_lines.append(line)
- content_dict = {}
- for line in ip_lines:
- key, value = line.split("\t")[0], line.split("\t")[1]
- content_dict[key] = value
- return content_dict
-
- def write(self):
- """
- write the changes into the file.
- """
- content_text = ""
- for key, value in self.content.items():
- content_text += f"\n{key}\t{value}"
- with open(self.path, "w") as file:
- file.write(content_text)
-
- def remove(self, ip):
- """
- remove the ip and its hostname from hosts file
- Args:
- ip (str) : the ip address
- """
- del self.content[ip]
-
- def add(self, ip, domain):
- """
- add new entry to the hosts file
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
- def set_hostname(self, ip, domain):
- """
- update the hostname for ip
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
- def exists(self, ip):
- """
- check for the existence of the ip in hosts file.
- Args:
- ip (str) : the ip address
- Return:
- boolen expression
- """
- return ip in self.content
-
- def get_hostname(self, ip):
- """
- get the hostname for ip
- Args:
- ip (str) : the ip address
- Returns:
- the hostname for the ip address
- """
- return self.content[ip]
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class HostsFile
-(hosts_file_path)
-
-
-
-
-Source code
-
class HostsFile:
- def __init__(self, hosts_file_path):
- self.path = hosts_file_path
- self.content = self._parse()
-
- def _parse(self):
- with open(self.path, "r") as file:
- content_text = file.read()
- content_lines = content_text.splitlines()
- ip_lines = []
- regex = r"""\d+\.\d+\.\d+\.\d+"""
- for line in content_lines:
- if re.search(regex, line):
- ip_lines.append(line)
- content_dict = {}
- for line in ip_lines:
- key, value = line.split("\t")[0], line.split("\t")[1]
- content_dict[key] = value
- return content_dict
-
- def write(self):
- """
- write the changes into the file.
- """
- content_text = ""
- for key, value in self.content.items():
- content_text += f"\n{key}\t{value}"
- with open(self.path, "w") as file:
- file.write(content_text)
-
- def remove(self, ip):
- """
- remove the ip and its hostname from hosts file
- Args:
- ip (str) : the ip address
- """
- del self.content[ip]
-
- def add(self, ip, domain):
- """
- add new entry to the hosts file
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
- def set_hostname(self, ip, domain):
- """
- update the hostname for ip
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
- def exists(self, ip):
- """
- check for the existence of the ip in hosts file.
- Args:
- ip (str) : the ip address
- Return:
- boolen expression
- """
- return ip in self.content
-
- def get_hostname(self, ip):
- """
- get the hostname for ip
- Args:
- ip (str) : the ip address
- Returns:
- the hostname for the ip address
- """
- return self.content[ip]
-
-
Methods
-
-
-def add(self, ip, domain)
-
-
-
add new entry to the hosts file
-
Args
-
ip (str) : the ip address
-domain (str) : the host name
-
-Source code
-
def add(self, ip, domain):
- """
- add new entry to the hosts file
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
-
-
-def exists(self, ip)
-
-
-
check for the existence of the ip in hosts file.
-
Args
-
ip (str) : the ip address
-
Return
-
boolen expression
-
-Source code
-
def exists(self, ip):
- """
- check for the existence of the ip in hosts file.
- Args:
- ip (str) : the ip address
- Return:
- boolen expression
- """
- return ip in self.content
-
-
-
-def get_hostname(self, ip)
-
-
-
get the hostname for ip
-
Args
-
ip (str) : the ip address
-
Returns
-
-
thehostnamefortheipaddress
-
-
-
-Source code
-
def get_hostname(self, ip):
- """
- get the hostname for ip
- Args:
- ip (str) : the ip address
- Returns:
- the hostname for the ip address
- """
- return self.content[ip]
-
-
-
-def remove(self, ip)
-
-
-
remove the ip and its hostname from hosts file
-
Args
-
ip (str) : the ip address
-
-Source code
-
def remove(self, ip):
- """
- remove the ip and its hostname from hosts file
- Args:
- ip (str) : the ip address
- """
- del self.content[ip]
-
-
-
-def set_hostname(self, ip, domain)
-
-
-
update the hostname for ip
-
Args
-
ip (str) : the ip address
-domain (str) : the host name
-
-Source code
-
def set_hostname(self, ip, domain):
- """
- update the hostname for ip
- Args:
- ip (str) : the ip address
- domain (str) : the host name
- """
- self.content[ip] = domain
-
-
-
-def write(self)
-
-
-
write the changes into the file.
-
-Source code
-
def write(self):
- """
- write the changes into the file.
- """
- content_text = ""
- for key, value in self.content.items():
- content_text += f"\n{key}\t{value}"
- with open(self.path, "w") as file:
- file.write(content_text)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/sals/process/process.html b/docs/api/jumpscale/sals/process/process.html
deleted file mode 100644
index 721e4327b..000000000
--- a/docs/api/jumpscale/sals/process/process.html
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-jumpscale.sals.process.process API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
import inspect
-import sys
-from functools import wraps
-from jumpscale.loader import j
-
-
-def actor_method(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- # verify args and kwargs types
- signature = inspect.signature(func)
- try:
- bound = signature.bind(*args, **kwargs)
- except TypeError as e:
- raise j.exceptions.Value(str(e))
-
- for name, value in bound.arguments.items():
- annotation = signature.parameters[name].annotation
- if annotation not in (None, inspect._empty) and not isinstance(value, annotation):
- raise j.exceptions.Value(
- f"parameter ({name}) supposed to be of type ({annotation.__name__}), but found ({type(value).__name__})"
- )
-
- # call method
- result = func(*bound.args, **bound.kwargs)
- # verify result type
- return_type = signature.return_annotation
- if return_type is inspect._empty or return_type is None:
- return_type = type(None)
-
- if not isinstance(result, return_type):
- raise j.exceptions.Value(f"method is supposed to return ({return_type}), but it returned ({type(result)})")
-
- return result
-
- return wrapper
-
-
-class BaseActor:
- def __init__(self):
- self.path = None
-
- @actor_method
- def info(self) -> dict:
- info = {}
- info["path"] = self.path
- info["methods"] = {}
-
- methods = inspect.getmembers(self, predicate=inspect.ismethod)
- for name, attr in methods:
- if name.startswith("_"):
- continue
-
- signature = inspect.signature(attr)
- info["methods"][name] = {}
- info["methods"][name]["args"] = []
- info["methods"][name]["doc"] = attr.__doc__ or ""
-
- for parameter_name, parameter in signature.parameters.items():
- info["methods"][name]["args"].append((parameter_name, parameter.annotation.__name__))
-
- return info
-
- def __validate_actor__(self):
- def validate_annotation(annotation, annotated):
- if annotation is None or annotation is inspect._empty:
- return
-
- if not (inspect.isclass(annotation) and annotation.__class__ == type):
- raise ValueError("annotation must be a class type")
-
- if annotation not in (str, int, float, list, tuple, dict, bool):
- if annotation.__module__ == "builtins":
- raise ValueError(f"unsupported type ({annotation.__name__})")
-
- for method in ["to_dict", "from_dict"]:
- if method not in dir(annotation):
- raise ValueError(
- f"type ({annotation.__name__}) which annotate {annotated} doesn't have {method} method"
- )
-
- result = {"valid": True, "errors": {}}
- methods = inspect.getmembers(self, predicate=inspect.ismethod)
- for method_name, method_callable in methods:
- if method_name.startswith("_"):
- continue
-
- result["errors"][method_name] = []
- signature = inspect.signature(method_callable)
- try:
- validate_annotation(signature.return_annotation, "return")
- except ValueError as e:
- result["errors"][method_name].append(str(e))
-
- for name, parameter in signature.parameters.items():
- try:
- validate_annotation(parameter.annotation, f"parameter ({name})")
- except ValueError as e:
- result["errors"][method_name].append(str(e))
-
- if any(result["errors"].values()):
- result["valid"] = False
-
- return result
-
-
-
-
-
-
-
-
Functions
-
-
-def actor_method(func)
-
-
-
-
-Source code
-
def actor_method(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- # verify args and kwargs types
- signature = inspect.signature(func)
- try:
- bound = signature.bind(*args, **kwargs)
- except TypeError as e:
- raise j.exceptions.Value(str(e))
-
- for name, value in bound.arguments.items():
- annotation = signature.parameters[name].annotation
- if annotation not in (None, inspect._empty) and not isinstance(value, annotation):
- raise j.exceptions.Value(
- f"parameter ({name}) supposed to be of type ({annotation.__name__}), but found ({type(value).__name__})"
- )
-
- # call method
- result = func(*bound.args, **bound.kwargs)
- # verify result type
- return_type = signature.return_annotation
- if return_type is inspect._empty or return_type is None:
- return_type = type(None)
-
- if not isinstance(result, return_type):
- raise j.exceptions.Value(f"method is supposed to return ({return_type}), but it returned ({type(result)})")
-
- return result
-
- return wrapper
-
-
-
-
-
-
Classes
-
-
-class BaseActor
-
-
-
-
-Source code
-
class BaseActor:
- def __init__(self):
- self.path = None
-
- @actor_method
- def info(self) -> dict:
- info = {}
- info["path"] = self.path
- info["methods"] = {}
-
- methods = inspect.getmembers(self, predicate=inspect.ismethod)
- for name, attr in methods:
- if name.startswith("_"):
- continue
-
- signature = inspect.signature(attr)
- info["methods"][name] = {}
- info["methods"][name]["args"] = []
- info["methods"][name]["doc"] = attr.__doc__ or ""
-
- for parameter_name, parameter in signature.parameters.items():
- info["methods"][name]["args"].append((parameter_name, parameter.annotation.__name__))
-
- return info
-
- def __validate_actor__(self):
- def validate_annotation(annotation, annotated):
- if annotation is None or annotation is inspect._empty:
- return
-
- if not (inspect.isclass(annotation) and annotation.__class__ == type):
- raise ValueError("annotation must be a class type")
-
- if annotation not in (str, int, float, list, tuple, dict, bool):
- if annotation.__module__ == "builtins":
- raise ValueError(f"unsupported type ({annotation.__name__})")
-
- for method in ["to_dict", "from_dict"]:
- if method not in dir(annotation):
- raise ValueError(
- f"type ({annotation.__name__}) which annotate {annotated} doesn't have {method} method"
- )
-
- result = {"valid": True, "errors": {}}
- methods = inspect.getmembers(self, predicate=inspect.ismethod)
- for method_name, method_callable in methods:
- if method_name.startswith("_"):
- continue
-
- result["errors"][method_name] = []
- signature = inspect.signature(method_callable)
- try:
- validate_annotation(signature.return_annotation, "return")
- except ValueError as e:
- result["errors"][method_name].append(str(e))
-
- for name, parameter in signature.parameters.items():
- try:
- validate_annotation(parameter.annotation, f"parameter ({name})")
- except ValueError as e:
- result["errors"][method_name].append(str(e))
-
- if any(result["errors"].values()):
- result["valid"] = False
-
- return result
@actor_method
-def info(self) -> dict:
- info = {}
- info["path"] = self.path
- info["methods"] = {}
-
- methods = inspect.getmembers(self, predicate=inspect.ismethod)
- for name, attr in methods:
- if name.startswith("_"):
- continue
-
- signature = inspect.signature(attr)
- info["methods"][name] = {}
- info["methods"][name]["args"] = []
- info["methods"][name]["doc"] = attr.__doc__ or ""
-
- for parameter_name, parameter in signature.parameters.items():
- info["methods"][name]["args"].append((parameter_name, parameter.annotation.__name__))
-
- return info
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/servers/gedis/example_actor.html b/docs/api/jumpscale/servers/gedis/example_actor.html
deleted file mode 100644
index efd9ebefc..000000000
--- a/docs/api/jumpscale/servers/gedis/example_actor.html
+++ /dev/null
@@ -1,475 +0,0 @@
-
-
-
-
-
-
-jumpscale.servers.gedis.example_actor API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.servers.gedis.example_actor
-
-
-
-Source code
-
from jumpscale.servers.gedis.baseactor import BaseActor, actor_method
-from typing import Sequence
-from jumpscale.loader import j
-import inspect, sys
-
-
-class TestObject:
- def __init__(self):
- self.attr = None
-
- def to_dict(self):
- return self.__dict__
-
- def from_dict(self, ddict):
- self.__dict__ = ddict
-
-
-class Example(BaseActor):
- @actor_method
- def add_two_ints(self, x: int, y: int) -> int:
- """Adds two ints
-
- Arguments:
- x {int} -- first int
- y {int} -- second int
-
- Returns:
- int -- the sum of the two ints
- """
- return x + y
-
- @actor_method
- def concate_two_strings(self, x: str, y: str) -> str:
- """Concate two strings
-
- Arguments:
- x {str} -- first string
- y {str} -- second string
-
- Returns:
- str -- the concate of the two strings
- """
- return x + y
-
- @actor_method
- def modify_object(self, myobj: list, new_value: int) -> list:
- """Modify atrribute attr of the given object
-
- Arguments:
- myobj {TestObject} -- the object to be modified
-
- Returns:
- TestObject -- modified object
- """
- for i in range(len(myobj)):
- myobj[i].attr = new_value * (i + 1)
- return myobj
-
-
-Actor = Example
-
-
-
-
-
-
-
-
-
-
Classes
-
-
-class Actor
-
-
-
-
-Source code
-
class Example(BaseActor):
- @actor_method
- def add_two_ints(self, x: int, y: int) -> int:
- """Adds two ints
-
- Arguments:
- x {int} -- first int
- y {int} -- second int
-
- Returns:
- int -- the sum of the two ints
- """
- return x + y
-
- @actor_method
- def concate_two_strings(self, x: str, y: str) -> str:
- """Concate two strings
-
- Arguments:
- x {str} -- first string
- y {str} -- second string
-
- Returns:
- str -- the concate of the two strings
- """
- return x + y
-
- @actor_method
- def modify_object(self, myobj: list, new_value: int) -> list:
- """Modify atrribute attr of the given object
-
- Arguments:
- myobj {TestObject} -- the object to be modified
-
- Returns:
- TestObject -- modified object
- """
- for i in range(len(myobj)):
- myobj[i].attr = new_value * (i + 1)
- return myobj
@actor_method
-def add_two_ints(self, x: int, y: int) -> int:
- """Adds two ints
-
- Arguments:
- x {int} -- first int
- y {int} -- second int
-
- Returns:
- int -- the sum of the two ints
- """
- return x + y
-
-
-
-def concate_two_strings(self, x, y)
-
-
-
Concate two strings
-
Arguments
-
x {str} – first string
-y {str} – second string
-
Returns
-
-
str – theconcate of thetwostrings
-
-
-
-Source code
-
@actor_method
-def concate_two_strings(self, x: str, y: str) -> str:
- """Concate two strings
-
- Arguments:
- x {str} -- first string
- y {str} -- second string
-
- Returns:
- str -- the concate of the two strings
- """
- return x + y
@actor_method
-def modify_object(self, myobj: list, new_value: int) -> list:
- """Modify atrribute attr of the given object
-
- Arguments:
- myobj {TestObject} -- the object to be modified
-
- Returns:
- TestObject -- modified object
- """
- for i in range(len(myobj)):
- myobj[i].attr = new_value * (i + 1)
- return myobj
-
-
-
-
-
-class Example
-
-
-
-
-Source code
-
class Example(BaseActor):
- @actor_method
- def add_two_ints(self, x: int, y: int) -> int:
- """Adds two ints
-
- Arguments:
- x {int} -- first int
- y {int} -- second int
-
- Returns:
- int -- the sum of the two ints
- """
- return x + y
-
- @actor_method
- def concate_two_strings(self, x: str, y: str) -> str:
- """Concate two strings
-
- Arguments:
- x {str} -- first string
- y {str} -- second string
-
- Returns:
- str -- the concate of the two strings
- """
- return x + y
-
- @actor_method
- def modify_object(self, myobj: list, new_value: int) -> list:
- """Modify atrribute attr of the given object
-
- Arguments:
- myobj {TestObject} -- the object to be modified
-
- Returns:
- TestObject -- modified object
- """
- for i in range(len(myobj)):
- myobj[i].attr = new_value * (i + 1)
- return myobj
@actor_method
-def add_two_ints(self, x: int, y: int) -> int:
- """Adds two ints
-
- Arguments:
- x {int} -- first int
- y {int} -- second int
-
- Returns:
- int -- the sum of the two ints
- """
- return x + y
-
-
-
-def concate_two_strings(self, x, y)
-
-
-
Concate two strings
-
Arguments
-
x {str} – first string
-y {str} – second string
-
Returns
-
-
str – theconcate of thetwostrings
-
-
-
-Source code
-
@actor_method
-def concate_two_strings(self, x: str, y: str) -> str:
- """Concate two strings
-
- Arguments:
- x {str} -- first string
- y {str} -- second string
-
- Returns:
- str -- the concate of the two strings
- """
- return x + y
@property
-def actors(self):
- """Lists saved actors
-
- Returns:
- list -- List of saved actors
- """
- return self._actors
-
-
-
var enable_system_actor
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var host
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var port
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var run_async
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
-
Methods
-
-
-def actor_add(self, actor_name, actor_path)
-
-
-
Adds an actor to the server
-
Arguments
-
actor_name {str} – Actor name
-actor_path {str} – Actor absolute path
-
Raises
-
-
j.exceptions.Value: raisesifactornameismatchedone of thereservedactornames
def actor_add(self, actor_name: str, actor_path: str):
- """Adds an actor to the server
-
- Arguments:
- actor_name {str} -- Actor name
- actor_path {str} -- Actor absolute path
-
- Raises:
- j.exceptions.Value: raises if actor name is matched one of the reserved actor names
- j.exceptions.Value: raises if actor name is not a valid identifier
- """
- if actor_name in RESERVED_ACTOR_NAMES:
- raise j.exceptions.Value("Invalid actor name")
-
- if not actor_name.isidentifier():
- raise j.exceptions.Value(f"Actor name should be a valid identifier")
-
- self._actors[actor_name] = actor_path
-
-
-
-def actor_delete(self, actor_name)
-
-
-
Removes an actor from the server
-
Arguments
-
actor_name {str} – Actor name
-
-Source code
-
def actor_delete(self, actor_name: str):
- """Removes an actor from the server
-
- Arguments:
- actor_name {str} -- Actor name
- """
- self._actors.pop(actor_name, None)
-
-
-
-def start(self)
-
-
-
Starts the server
-
-Source code
-
def start(self):
- """Starts the server
- """
- # handle signals
- for signal_type in (SIGTERM, SIGKILL):
- gevent.signal(signal_type, self.stop)
-
- # register system actor if enabled
- if self.enable_system_actor:
- self._register_actor("system", self._system_actor)
-
- self._core_actor.set_server(self)
- self._system_actor.set_server(self)
-
- # register saved actors
- for actor_name, actor_path in self._actors.items():
- self._system_actor.register_actor(actor_name, actor_path)
-
- # start the server
- self._server = StreamServer((self.host, self.port), self._on_connection, spawn=Pool())
- self._server.reuse_addr = True
- self._server.start()
-
- j.logger.info(f"Gedis server is started at {self.host}:{self.port}...")
-
-
-
-def stop(self)
-
-
-
Stops the server
-
-Source code
-
def stop(self):
- """Stops the server
- """
- j.logger.info("Shutting down...")
- self._server.stop()
@actor_method
-def list_actors(self) -> list:
- """List available actors
-
- Returns:
- list -- list of available actors
- """
- return list(self._server._loaded_actors.keys())
-
-
-
-def set_server(self, server)
-
-
-
-
-Source code
-
def set_server(self, server):
- self._server = server
-
-
-
-
-
-class SystemActor
-
-
-
-
-Source code
-
class SystemActor(BaseActor):
- def __init__(self):
- super().__init__()
- self._server = None
- self.path = __file__
-
- def set_server(self, server):
- self._server = server
-
- @actor_method
- def register_actor(self, actor_name: str, actor_path: str, force_reload: bool = False) -> bool:
- """
- Register new actor
-
- Args:
- actor_name (str): actor name within gedis server.
- actor_path (str): actor path on gedis server machine.
- force_reload (bool, optional): reload the module if set. Defaults to False.
-
- Raises:
- j.exceptions.Validation: in case the actor is not valid
-
- Returns:
- bool: True if registered
- """
- module = j.tools.codeloader.load_python_module(actor_path, force_reload=force_reload)
- actor = module.Actor()
- actor.path = actor_path
- result = actor.__validate_actor__()
-
- if not result["valid"]:
- raise j.exceptions.Validation(
- "Actor {} is not valid, check the following errors {}".format(actor_name, result["errors"])
- )
-
- self._server._register_actor(actor_name, actor)
- return True
-
- @actor_method
- def unregister_actor(self, actor_name: str) -> bool:
- """Register actor
-
- Arguments:
- actor_name {str} -- actor name
-
- Returns:
- bool -- True if actors is unregistered
- """
- self._server._unregister_actor(actor_name)
- return True
@actor_method
-def register_actor(self, actor_name: str, actor_path: str, force_reload: bool = False) -> bool:
- """
- Register new actor
-
- Args:
- actor_name (str): actor name within gedis server.
- actor_path (str): actor path on gedis server machine.
- force_reload (bool, optional): reload the module if set. Defaults to False.
-
- Raises:
- j.exceptions.Validation: in case the actor is not valid
-
- Returns:
- bool: True if registered
- """
- module = j.tools.codeloader.load_python_module(actor_path, force_reload=force_reload)
- actor = module.Actor()
- actor.path = actor_path
- result = actor.__validate_actor__()
-
- if not result["valid"]:
- raise j.exceptions.Validation(
- "Actor {} is not valid, check the following errors {}".format(actor_name, result["errors"])
- )
-
- self._server._register_actor(actor_name, actor)
- return True
-
-
-
-def set_server(self, server)
-
-
-
-
-Source code
-
def set_server(self, server):
- self._server = server
-
-
-
-def unregister_actor(self, actor_name)
-
-
-
Register actor
-
Arguments
-
actor_name {str} – actor name
-
Returns
-
-
bool – Trueifactorsisunregistered
-
-
-
-Source code
-
@actor_method
-def unregister_actor(self, actor_name: str) -> bool:
- """Register actor
-
- Arguments:
- actor_name {str} -- actor name
-
- Returns:
- bool -- True if actors is unregistered
- """
- self._server._unregister_actor(actor_name)
- return True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/servers/gedis_http/index.html b/docs/api/jumpscale/servers/gedis_http/index.html
deleted file mode 100644
index fc9d499ff..000000000
--- a/docs/api/jumpscale/servers/gedis_http/index.html
+++ /dev/null
@@ -1,485 +0,0 @@
-
-
-
-
-
-
-jumpscale.servers.gedis_http API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var client
-
-
-
-Source code
-
@property
-def client(self):
- if self._client is None:
- self._client = j.clients.gedis.get(self.instance_name)
- self._client.disable_deserialization = True
- return self._client
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
var port
-
-
getter method this property
-
will call _get_value, which would if the value is already defined
-and will get the default value if not
-
Returns
-
-
any
-
the field value
-
-
-Source code
-
def getter(self):
- """
- getter method this property
-
- will call `_get_value`, which would if the value is already defined
- and will get the default value if not
-
- Returns:
- any: the field value
- """
- return self._get_value(name, field)
-
-
-
-
Methods
-
-
-def enable_cors(self, fn, allow_cors=True)
-
-
-
-
-Source code
-
def enable_cors(self, fn, allow_cors=True):
- def _enable_cors(*args, **kwargs):
- # set CORS headers
- response.headers["Access-Control-Allow-Origin"] = "*"
- response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS, DELETE"
- response.headers[
- "Access-Control-Allow-Headers"
- ] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token"
-
- if request.method != "OPTIONS":
- # actual request; reply with the actual response
- return fn(*args, **kwargs)
-
- if allow_cors:
- return _enable_cors
- else:
- return fn
-
-
-
-def handler(self, package, actor, method)
-
-
-
-
-Source code
-
def handler(self, package, actor, method):
- actors = self.client.actors
-
- actor = getattr(actors, f"{package}_{actor}", None)
- if not actor:
- return self.make_response(400, {"error": "actor not found"})
-
- method = getattr(actor, method, None)
- if not method:
- return self.make_response(400, {"error": "method not found"})
-
- kwargs = request.json or dict()
- response = method(**kwargs)
-
- if not response.success:
- if response.error_type == GedisErrorTypes.NOT_FOUND:
- return self.make_response(404, {"error": response.error})
-
- elif response.error_type == GedisErrorTypes.BAD_REQUEST:
- return self.make_response(400, {"error": response.error})
-
- elif response.error_type == GedisErrorTypes.PERMISSION_ERROR:
- return self.make_response(403, {"error": response.error})
-
- else:
- return self.make_response(500, {"error": response.error})
-
- return self.make_response(200, response.result)
@staticmethod
-def install(name, image, development: bool = False, volumes=None):
- """Creates a container
-
- Args:
- name (str): name of the container
- image (str): container image.
- development (bool, optional): if true will mount codedir. Defaults to False.
- volumes (dict, optional): paths to be mounted
-
- Raises:
- Value: Container with specified name already exists
- """
- if docker_client.exists(name):
- raise Value("Container with specified name already exists")
-
- volumes = volumes or {}
- if development:
- volumes = {Dirs.CODEDIR: {"bind": "/sandbox/code", "mode": "rw"}}
-
- print(f"Creating container {name}")
- return docker_client.run(name, image, entrypoint="/sbin/my_init", volumes=volumes, detach=True)
-
-
-
-def start(name)
-
-
-
Starts an existing container
-
Args
-
-
name : str
-
name of the container
-
-
-
-Expand source code
-
-
@staticmethod
-def start(name):
- """Starts an existing container
-
- Args:
- name (str): name of the container
- """
- if not docker_client.exists(name):
- raise Value("Container with specified name doesn't exist")
- docker_client.start(name)
-
-
-
-def stop(name)
-
-
-
Stops an existing container
-
Args
-
-
name : str
-
name of the container
-
-
-
-Expand source code
-
-
@staticmethod
-def stop(name):
- """Stops an existing container
-
- Args:
- name (str): name of the container
- """
- if not docker_client.exists(name):
- raise Value("Container with specified name doesn't exist")
- docker_client.stop(name)
class IdentityManager:
- def __init__(self, identity: str = "", email: str = None, words: str = None, explorer: str = None):
- self.identity = identity
- self.email = email
- self.words = words
- self.explorer = explorer
-
- def reset(self):
- self.identity = ""
- self.email = ""
- self.words = ""
- self.explorer = ""
-
- def _check_keys(self, user_explorer_key, user_app):
- if not user_app:
- return True
- pub_key_app = base64.decode(user_app["publicKey"])
- if binascii.unhexlify(user_explorer_key) != pub_key_app:
- return False
- return True
-
- def _get_user(self):
- response = requests.get(f"https://login.threefold.me/api/users/{self.identity}")
- if response.status_code == 404:
- raise exceptions.Value(
- "\nThis identity does not exist in 3bot mobile app connect, Please create an idenity first using 3Bot Connect mobile Application\n"
- )
- userdata = response.json()
-
- resp = requests.get("https://{}/explorer/users".format(self.explorer), params={"name": self.identity})
- if resp.status_code == 404 or resp.json() == []:
- # creating new user
- user = {}
- user["name"] = userdata["doublename"]
- user["pubkey"] = base64.decode(userdata["publicKey"]).hex()
- printcolors(
- f"\nWelcome {{CYAN}}{userdata['doublename']}{{WHITE}}. Creating a new record on {{CYAN}}{self.explorer}{{RESET}}.\n"
- )
- return user, userdata
- else:
- users = resp.json()
-
- if not self._check_keys(users[0]["pubkey"], userdata):
- raise exceptions.Value(
- f"\nYour 3bot on {self.explorer} seems to have been previously registered with a different public key.\n"
- f"The identity of {self.identity} is mismatched with 3bot connect app"
- "Please contact support.grid.tf to reset it.\n"
- "Note: use the same email registered on the explorer to contact support otherwise we cannot reset the account.\n"
- )
-
- if users:
- return (users[0], userdata)
- return None, userdata
-
- def _check_email(self, email):
- resp = requests.get("https://{}/explorer/users".format(self.explorer), params={"email": email})
- users = resp.json()
- if users:
- if users[0]["name"] == self.identity:
- return True
- else:
- return False
- else:
- return True
-
- def ask_identity(self, identity=None, explorer=None):
- def _fill_identity_args(identity, explorer):
- def fill_words():
- words = ask_string("Copy the phrase from your 3bot Connect app here: ")
- self.words = words
-
- def fill_identity():
- identity = ask_string("what is your threebot name (identity)? ")
- if "." not in identity:
- identity += ".3bot"
- self.identity = identity
-
- if identity:
- if self.identity != identity and self.identity:
- self.reset()
- self.identity = identity
-
- if explorer:
- self.explorer = explorer
- elif not self.explorer:
- response = ask_choice(
- "Which network would you like to register to? ", ["mainnet", "testnet", "devnet", "none"]
- )
- self.explorer = NETWORKS.get(response, None)
- if not self.explorer:
- return True
-
- user, user_app = None, None
- while not user:
- fill_identity()
- try:
- user, user_app = self._get_user()
- except exceptions.Value as e:
- response = ask_choice(f"{e}What would you like to do? ", CHOICES)
- if response == RESTART_CHOICE:
- return False
-
- while not self.email:
- self.email = ask_string("What is the email address associated with your identity? ")
- if self._check_email(self.email):
- break
- else:
- self.email = None
- response = ask_choice(
- "This email is currently associated with another identity. What would you like to do? ",
- CHOICES,
- )
- if response == RESTART_CHOICE:
- return False
-
- print("Configured email for this identity is {}".format(self.email))
-
- # time to do validation of words
- hexkey = None
- while True:
- if not self.words:
- fill_words()
- try:
- seed = mnemonic.mnemonic_to_key(self.words.strip())
- hexkey = NACL(seed).get_verify_key_hex()
- if (user and hexkey != user["pubkey"]) or not self._check_keys(hexkey, user_app):
- raise Exception
- else:
- return True
- except Exception:
- choice = ask_choice(
- "\nSeems one or more more words entered is invalid.\nWhat would you like to do? ", CHOICES,
- )
- if choice == RESTART_CHOICE:
- return False
- fill_words()
-
- while True:
- if _fill_identity_args(identity, explorer):
- identity_info = IdentityInfo(self.identity, self.email, self.words, self.explorer)
- return identity_info
def ask_identity(self, identity=None, explorer=None):
- def _fill_identity_args(identity, explorer):
- def fill_words():
- words = ask_string("Copy the phrase from your 3bot Connect app here: ")
- self.words = words
-
- def fill_identity():
- identity = ask_string("what is your threebot name (identity)? ")
- if "." not in identity:
- identity += ".3bot"
- self.identity = identity
-
- if identity:
- if self.identity != identity and self.identity:
- self.reset()
- self.identity = identity
-
- if explorer:
- self.explorer = explorer
- elif not self.explorer:
- response = ask_choice(
- "Which network would you like to register to? ", ["mainnet", "testnet", "devnet", "none"]
- )
- self.explorer = NETWORKS.get(response, None)
- if not self.explorer:
- return True
-
- user, user_app = None, None
- while not user:
- fill_identity()
- try:
- user, user_app = self._get_user()
- except exceptions.Value as e:
- response = ask_choice(f"{e}What would you like to do? ", CHOICES)
- if response == RESTART_CHOICE:
- return False
-
- while not self.email:
- self.email = ask_string("What is the email address associated with your identity? ")
- if self._check_email(self.email):
- break
- else:
- self.email = None
- response = ask_choice(
- "This email is currently associated with another identity. What would you like to do? ",
- CHOICES,
- )
- if response == RESTART_CHOICE:
- return False
-
- print("Configured email for this identity is {}".format(self.email))
-
- # time to do validation of words
- hexkey = None
- while True:
- if not self.words:
- fill_words()
- try:
- seed = mnemonic.mnemonic_to_key(self.words.strip())
- hexkey = NACL(seed).get_verify_key_hex()
- if (user and hexkey != user["pubkey"]) or not self._check_keys(hexkey, user_app):
- raise Exception
- else:
- return True
- except Exception:
- choice = ask_choice(
- "\nSeems one or more more words entered is invalid.\nWhat would you like to do? ", CHOICES,
- )
- if choice == RESTART_CHOICE:
- return False
- fill_words()
-
- while True:
- if _fill_identity_args(identity, explorer):
- identity_info = IdentityInfo(self.identity, self.email, self.words, self.explorer)
- return identity_info
container image. Defaults to "threefoldtech/js-ng:latest".
-
identity : str, optional
-
threebot name. Defaults to None.
-
email : str, optional
-
threebot email. Defaults to None.
-
words : str, optional
-
seed phrase of the user. Defaults to None.
-
explorer : str, optional
-
which explorer network to use: mainnet, testnet, devnet. Defaults to None.
-
development : bool, optional
-
if true will mount codedir. Defaults to False.
-
-
Raises
-
-
Value
-
Container with specified name already exists
-
Value
-
explorer not in mainnet, testnet, devnet
-
-
-
-Expand source code
-
-
@staticmethod
-def install(
- name=None, image=None, identity=None, email=None, words=None, explorer=None, development: bool = None,
-):
- """Creates a threebot container
-
- Args:
- name (str, optional): name of the container. Defaults to 3bot-ng
- image (str, optional): container image. Defaults to "threefoldtech/js-ng:latest".
- identity (str, optional): threebot name. Defaults to None.
- email (str, optional): threebot email. Defaults to None.
- words (str, optional): seed phrase of the user. Defaults to None.
- explorer (str, optional): which explorer network to use: mainnet, testnet, devnet. Defaults to None.
- development (bool, optional): if true will mount codedir. Defaults to False.
-
- Raises:
- Value: Container with specified name already exists
- Value: explorer not in mainnet, testnet, devnet
- """
- if development is None:
- development = settings.expert
- name = name or DEFAULT_CONTAINER_NAME
- current_version = get_current_version()
- image = image or f"{DEFAULT_IMAGE}:{current_version}"
-
- pers_path = f"{PERSISTENT_STORE}/{name}"
- configure = not os.path.exists(pers_path)
- if configure:
- identity = IdentityManager(identity, email, words, explorer)
- identity, email, words, explorer = identity.ask_identity()
-
- os.makedirs(PERSISTENT_STORE, exist_ok=True)
- volumes = {pers_path: {"bind": "/root/.config/jumpscale", "mode": "rw"}}
-
- container = Container.install(name, image, development, volumes)
- container.exec_run(["redis-server", "--daemonize yes"])
-
- if configure:
- container.exec_run(["jsng", f"j.core.identity.new('default', '{identity}', '{email}', '{words}')"])
- container.exec_run(["jsng", "j.core.identity.set_default('default')"])
-
-
-
-def jsng(name='3bot-ng')
-
-
-
Get's shell in threebot
-
Args
-
-
name : str
-
name of the container (default: 3bot-ng)
-
-
-
-Expand source code
-
-
@staticmethod
-def jsng(name=DEFAULT_CONTAINER_NAME):
- """Get's shell in threebot
-
- Args:
- name (str): name of the container (default: 3bot-ng)
- """
- Container.exec(name, "jsng")
-
-
-
-def restart(name='3bot-ng')
-
-
-
restart threebot installation with container
-
Args
-
-
name : str
-
name of the container (default: 3bot-ng)
-
-
-
-Expand source code
-
-
@staticmethod
-def restart(name=DEFAULT_CONTAINER_NAME):
- """restart threebot installation with container
-
- Args:
- name (str): name of the container (default: 3bot-ng)
- """
- ThreeBot.stop(name=name)
- ThreeBot.start(name=name)
-
-
-
-def shell(name='3bot-ng')
-
-
-
Get's shell in threebot
-
Args
-
-
name : str
-
name of the container (default: 3bot-ng)
-
-
-
-Expand source code
-
-
@staticmethod
-def shell(name=DEFAULT_CONTAINER_NAME):
- """Get's shell in threebot
-
- Args:
- name (str): name of the container (default: 3bot-ng)
- """
- Container.exec(name, "bash")
-
-
-
-def start(name='3bot-ng')
-
-
-
Start threebot container with threebot server
-
Args
-
-
name : str
-
name of the container (default: 3bot-ng)
-
-
-
-Expand source code
-
-
@staticmethod
-def start(name=DEFAULT_CONTAINER_NAME):
- """Start threebot container with threebot server
-
- Args:
- name (str): name of the container (default: 3bot-ng)
- """
- Container.start(name)
- Container.exec(name, ["threebot", "start", "--background"])
-
-
-
-def stop(name='3bot-ng')
-
-
-
Stop threebot installation with container
-
Args
-
-
name : str
-
name of the container (default: 3bot-ng)
-
-
-
-Expand source code
-
-
@staticmethod
-def stop(name=DEFAULT_CONTAINER_NAME):
- """Stop threebot installation with container
-
- Args:
- name (str): name of the container (default: 3bot-ng)
- """
- if name in docker_client.list():
- Container.exec(name, ["threebot", "stop"])
- Container.stop(name)
- else:
- print("Container is already stopped")
Get an float response between two float on asked question
-
Arguments
-
mini {float} – the minimum value for the number
-maxi {float} – the maximum value for the number
-Keyword Arguments:
-prompt {str} – the question message (default: {"Type float :"})
-
Returns
-
-
float – theinputnumberontherangeprovided
-
-
-
-Source code
-
def ask_float_in_range(mini, maxi, prompt="Type float :"):
- """Get an float response between two float on asked question
-
- Arguments:
- mini {float} -- the minimum value for the number
- maxi {float} -- the maximum value for the number
-
- Keyword Arguments:
- prompt {str} -- the question message (default: {"Type float :"})
-
- Returns:
- float -- the input number on the range provided
- """
- try:
- answer = float(input(prompt))
- if mini <= answer <= maxi:
- return answer
- else:
- return ask_float_in_range(mini, maxi, prompt)
- except ValueError:
- return ask_float_in_range(mini, maxi, prompt)
-def ask_int_in_range(mini, maxi, prompt='Type int :')
-
-
-
Get an integer response between two integer on asked question
-
Arguments
-
mini {int} – the minimum value for the number
-maxi {int} – the maximum value for the number
-Keyword Arguments:
-prompt {str} – the question message (default: {"Type int :"})
-
Returns
-
-
int – theinputnumberontherangeprovided
-
-
-
-Source code
-
def ask_int_in_range(mini, maxi, prompt="Type int :"):
- """Get an integer response between two integer on asked question
-
- Arguments:
- mini {int} -- the minimum value for the number
- maxi {int} -- the maximum value for the number
-
- Keyword Arguments:
- prompt {str} -- the question message (default: {"Type int :"})
-
- Returns:
- int -- the input number on the range provided
- """
- try:
- answer = int(input(prompt))
- if mini <= answer <= maxi:
- return answer
- else:
- return ask_int_in_range(mini, maxi, prompt)
- except ValueError:
- return ask_int_in_range(mini, maxi, prompt)
-
-
-
-def ask_multi_choices(prompt='Add to choices : ', choices_list=[], to_save='s', to_quit='q')
-
-
-
Collect multi choices from list
-
Keyword Arguments:
-prompt {str} – the question method (default: {"Add to choices : "})
-choices_list {list} – the available options (default: {[]})
-to_save {str} – escape and save choices (default: {"s"})
-to_quit {str} – escape without saving (default: {"q"})
-
Returns
-
-
list – list of theselectedchoices
-
-
-
-Source code
-
def ask_multi_choices(prompt="Add to choices : ", choices_list=[], to_save="s", to_quit="q"):
- """Collect multi choices from list
-
- Keyword Arguments:
- prompt {str} -- the question method (default: {"Add to choices : "})
- choices_list {list} -- the available options (default: {[]})
- to_save {str} -- escape and save choices (default: {"s"})
- to_quit {str} -- escape without saving (default: {"q"})
-
- Returns:
- list -- list of the selected choices
- """
- selected_choices = []
- print(f"'{to_save}' to save and '{to_quit}' to quit")
- _print_choices(choices_list)
-
- while True:
- answer = input(prompt)
- if answer == to_quit:
- return []
- elif answer == to_save or answer == "":
- return selected_choices
- else:
- try:
- selected_choices.append(choices_list[int(answer) - 1])
- except (IndexError, ValueError):
- return ask_multi_choices(prompt, choices_list, to_save, to_quit)
Display a yes/no question and loop until a valid answer is entered
-
Keyword Arguments:
-prompt {str} – the question message (default: {'[y/n] :'})
-default {str} – the default answer if there is no answer (default: {"y"})
-valid {list} – the list of appropriate answers (default: {["y", "n"]})
-
Returns
-
-
str – theanswer
-
-
-
-Source code
-
def ask_yes_no(prompt="[y/n] :", default="y", valid=["y", "n"]):
- """Display a yes/no question and loop until a valid answer is entered
-
- Keyword Arguments:
- prompt {str} -- the question message (default: {'[y/n] :'})
- default {str} -- the default answer if there is no answer (default: {"y"})
- valid {list} -- the list of appropriate answers (default: {["y", "n"]})
-
- Returns:
- str -- the answer
- """
-
- answer = input(prompt)
- if answer in valid:
- return answer
- elif answer == "":
- return default
- else:
- return ask_yes_no(prompt, default, valid)
def namerecords_get(self, url="www.threefoldtoken.org"):
- """
- return ip addr for a full name
- """
- answer = self.resolver.query(url, "A")
-
- res = []
- for rr in answer:
- res.append(rr.address)
- return res
def nameservers_get(self, domain="threefoldtoken.org"):
- answer = self.resolver.query(domain, "NS")
-
- res = []
- for rr in answer:
- res.append(rr.target.to_text())
- return res
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/tools/imagelib/imagelib.html b/docs/api/jumpscale/tools/imagelib/imagelib.html
deleted file mode 100644
index 46d46768c..000000000
--- a/docs/api/jumpscale/tools/imagelib/imagelib.html
+++ /dev/null
@@ -1,302 +0,0 @@
-
-
-
-
-
-
-jumpscale.tools.imagelib.imagelib API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.tools.imagelib.imagelib
-
-
-
-Source code
-
import os
-from PIL import Image
-
-
-def get_list_files(dir_name):
- """returns a list of directories for all image files in a root folder
-
- Arguments:
- dir_name (str) : the directory of the root folder
-
- Returns:
- all_files (list) : the list of directories for all files in the root folder
- """
- # create a list of file and sub directories
- # names in the given directory
- files_list = os.listdir(dir_name)
- all_files = list()
- # Iterate over all the entries
- for entry in files_list:
- # Create full path
- full_path = os.path.join(dir_name, entry)
- # If entry is a directory then get the list of files in this directory
- if os.path.isdir(full_path):
- all_files = all_files + get_list_files(full_path)
- else:
- path_split = os.path.splitext(full_path)
- if path_split[1] in [".jpg", ".jpeg", ".png"]:
- all_files.append(full_path)
-
- return all_files
-
-
-def get_image(path):
- """returns an PIL.Image object by path
-
- Arguments:
- path (string) : the image path
-
- Returns:
- PIL.Image object
- """
- return Image.open(path)
-
-
-def resize(path, pathnew, width=1024):
- """resize an image
-
- Arguments:
- path (string) : the path of the image will be resized
- pathnew (string) : the path of new resized image
-
- Keyword Arguments:
- width (int) : the width of the new image , hieght is depending on it
-
- Returns:
- (string) : True if image resized successfully or the exception message if not
- """
- im = get_image(path)
- xnew = width
- x, y = im.size
- ynew = int(float(y) / (float(x) / float(xnew)))
- imnew = im.resize((xnew, ynew), Image.ANTIALIAS)
- try:
- imnew.save(pathnew)
- return "True"
- except Exception as e:
- return str(e)
-
-
-def resize_images_in_dir(folder, foldernew, width=1024):
- """resize images in folder
-
- Arguments:
- folder (string) : the path of the root folder in which images will be resized
- foldernew (string) : the path of the folder in which new images will be stored
-
- Keyword Arguments:
- width (int) : the width of the new images , hieght is depending on it
-
- Returns:
- (dict) : a dict with img path as key and its statue as value
- statue : True if image resized successfully or the exception message if not
- """
- img_list = get_list_files(folder)
- print(img_list)
- img_statue = {}
- for img in img_list:
- statue = resize(img, os.path.join(foldernew, os.path.basename(img)), width=width)
- img_statue[img] = statue
- return img_statue
-
-
-
-
-
-
-
-
Functions
-
-
-def get_image(path)
-
-
-
returns an PIL.Image object by path
-
Arguments
-
path (string) : the image path
-
Returns
-
-
PIL.Imageobject
-
-
-
-Source code
-
def get_image(path):
- """returns an PIL.Image object by path
-
- Arguments:
- path (string) : the image path
-
- Returns:
- PIL.Image object
- """
- return Image.open(path)
-
-
-
-def get_list_files(dir_name)
-
-
-
returns a list of directories for all image files in a root folder
-
Arguments
-
dir_name (str) : the directory of the root folder
-
Returns
-
-
all_files (list) : thelist of directoriesforallfilesintherootfolder
-
-
-
-Source code
-
def get_list_files(dir_name):
- """returns a list of directories for all image files in a root folder
-
- Arguments:
- dir_name (str) : the directory of the root folder
-
- Returns:
- all_files (list) : the list of directories for all files in the root folder
- """
- # create a list of file and sub directories
- # names in the given directory
- files_list = os.listdir(dir_name)
- all_files = list()
- # Iterate over all the entries
- for entry in files_list:
- # Create full path
- full_path = os.path.join(dir_name, entry)
- # If entry is a directory then get the list of files in this directory
- if os.path.isdir(full_path):
- all_files = all_files + get_list_files(full_path)
- else:
- path_split = os.path.splitext(full_path)
- if path_split[1] in [".jpg", ".jpeg", ".png"]:
- all_files.append(full_path)
-
- return all_files
-
-
-
-def resize(path, pathnew, width=1024)
-
-
-
resize an image
-
Arguments
-
path (string) : the path of the image will be resized
-pathnew (string) : the path of new resized image
-Keyword Arguments:
-width (int) : the width of the new image , hieght is depending on it
-
Returns
-
(string) : True if image resized successfully or the exception message if not
-
-Source code
-
def resize(path, pathnew, width=1024):
- """resize an image
-
- Arguments:
- path (string) : the path of the image will be resized
- pathnew (string) : the path of new resized image
-
- Keyword Arguments:
- width (int) : the width of the new image , hieght is depending on it
-
- Returns:
- (string) : True if image resized successfully or the exception message if not
- """
- im = get_image(path)
- xnew = width
- x, y = im.size
- ynew = int(float(y) / (float(x) / float(xnew)))
- imnew = im.resize((xnew, ynew), Image.ANTIALIAS)
- try:
- imnew.save(pathnew)
- return "True"
- except Exception as e:
- return str(e)
folder (string) : the path of the root folder in which images will be resized
-foldernew (string) : the path of the folder in which new images will be stored
-Keyword Arguments:
-width (int) : the width of the new images , hieght is depending on it
-
Returns
-
(dict) : a dict with img path as key and its statue as value
-statue : True if image resized successfully or the exception message if not
-
-Source code
-
def resize_images_in_dir(folder, foldernew, width=1024):
- """resize images in folder
-
- Arguments:
- folder (string) : the path of the root folder in which images will be resized
- foldernew (string) : the path of the folder in which new images will be stored
-
- Keyword Arguments:
- width (int) : the width of the new images , hieght is depending on it
-
- Returns:
- (dict) : a dict with img path as key and its statue as value
- statue : True if image resized successfully or the exception message if not
- """
- img_list = get_list_files(folder)
- print(img_list)
- img_statue = {}
- for img in img_list:
- statue = resize(img, os.path.join(foldernew, os.path.basename(img)), width=width)
- img_statue[img] = statue
- return img_statue
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/tools/imagelib/index.html b/docs/api/jumpscale/tools/imagelib/index.html
deleted file mode 100644
index 582b6d04f..000000000
--- a/docs/api/jumpscale/tools/imagelib/index.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
-jumpscale.tools.imagelib API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
from .poolexecutor import PoolExecutor
-
-"""
-
-def sleepf(howlong, name="fun"):
- print("{} is sleeping for {}".format(name, howlong))
- for i in range(howlong):
- print("{} is sleeping slept for {}".format(name, howlong - i))
- gevent.sleep(i)
-
-with j.tools.poolexecutor.PoolExecutor() as p:
- for i in range(5):
- p.task_add(sleepf, i, name="fun{}".format(i))
-
- gs = p.run()
- print(p.results(gs))
-
-
-"""
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/api/jumpscale/tools/profiler/index.html b/docs/api/jumpscale/tools/profiler/index.html
deleted file mode 100644
index 45ba0608d..000000000
--- a/docs/api/jumpscale/tools/profiler/index.html
+++ /dev/null
@@ -1,206 +0,0 @@
-
-
-
-
-
-
-jumpscale.tools.profiler API documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
Module jumpscale.tools.profiler
-
-
-
This module is used to do profiling for methods. profiling can be visulaized or just printed to stdout
-How to use it
-
@j.tools.profiler.profiled(visualized=True)
-def foo():
- for i in range(10):
- print("test")
-
-
to do visualizing, add (visualize=True) when u call profiled decorator
-example
-@j.tools.profiler.profiled() # this will print the profiling results to stdout
-j.tools.profiler.profiled(visualized=True) # will launce a server with the visualized profiling on <http://127.0.0.1:8080/snakeviz/%2Fsandbox%2Fcode%2Fgithub%2Fthreefoldtech%2Fjs-ng%2Fresult.prof>
-to change port and host
-j.tools.profiler.profiled(visualized=True, port="8008", host="0.0.0.0", print_data=True)
-this will print data to stdout and launce snakeviz server on this url
-<http://127.0.0.1:8080/snakeviz/foo>
-
-Source code
-
"""This module is used to do profiling for methods. profiling can be visulaized or just printed to stdout
-How to use it
-```
-@j.tools.profiler.profiled(visualized=True)
-def foo():
- for i in range(10):
- print("test")
-```
-to do visualizing, add (visualize=True) when u call profiled decorator
-example
-@j.tools.profiler.profiled() # this will print the profiling results to stdout
-j.tools.profiler.profiled(visualized=True) # will launce a server with the visualized profiling on `http://127.0.0.1:8080/snakeviz/%2Fsandbox%2Fcode%2Fgithub%2Fthreefoldtech%2Fjs-ng%2Fresult.prof`
-to change port and host
-j.tools.profiler.profiled(visualized=True, port="8008", host="0.0.0.0", print_data=True)
-this will print data to stdout and launce snakeviz server on this url
-`http://127.0.0.1:8080/snakeviz/foo`
-"""
-from cProfile import Profile
-from pstats import Stats
-from snakeviz.main import app
-import tornado
-from subprocess import Popen
-import socket
-
-
-def profiled(visualized=False, host="127.0.0.1", port="8080", print_data=False):
- def do_profiling(func):
- def wrapper(*args, **kwargs):
- profiler = Profile()
- result = profiler.runcall(func, *args, **kwargs)
- if print_data:
- profiler.print_stats()
- filename = func.__name__
- profiler.dump_stats(filename)
- if visualized:
- visualize(filename, host, port)
- return result
-
- return wrapper
-
- return do_profiling
-
-
-def visualize(filename, host="127.0.0.1", port="8080"):
- try:
- Stats(filename)
- except Exception as e:
- print(f"{filename} is not a valid stats file")
- raise e
- try:
- conn = app.listen(port, address=host)
- except socket.error as e:
- print("Port {0} already in use.".format(port))
- raise e
-
- url = "http://{0}:{1}/snakeviz/{2}".format(host, port, filename)
- print(f"snakeviz web server started on {host}:{port}; enter Ctrl-C to exit")
- print(url)
-
- try:
- tornado.ioloop.IOLoop.instance().start()
- except KeyboardInterrupt:
- conn.stop()
- print("\nBye!")
-
- return 0
registers domain in coredns (needs to be authoritative)
-
e.g: ahmed.bots.grid.tf
-
requires nameserver on bots.grid.tf (authoritative)
-- ahmed is threebot_name
-- bots_domain is bots.grid.tf
-
:param threebot_name: threebot_name
-:type threebot_name: str
-:param bots_domain: str, defaults to "bots.grid.tf."
-:type bots_domain: str, optional
-:param record_type: valid dns record (a, aaaa, txt, srv..), defaults to "a"
-:type record_type: str, optional
-:param records: records list, defaults to None
-:type records: [type], optional is [ {"ip":machine ip}] in case of a/aaaa records
-
-Source code
-
def domain_register(threebot_name, bots_domain="bots.grid.tf.", record_type="a", records=None):
- """registers domain in coredns (needs to be authoritative)
-
- e.g: ahmed.bots.grid.tf
-
- requires nameserver on bots.grid.tf (authoritative)
- - ahmed is threebot_name
- - bots_domain is bots.grid.tf
-
- :param threebot_name: threebot_name
- :type threebot_name: str
- :param bots_domain: str, defaults to "bots.grid.tf."
- :type bots_domain: str, optional
- :param record_type: valid dns record (a, aaaa, txt, srv..), defaults to "a"
- :type record_type: str, optional
- :param records: records list, defaults to None
- :type records: [type], optional is [ {"ip":machine ip}] in case of a/aaaa records
- """
- if not bots_domain.endswith("."):
- bots_domain += "."
- data = {}
- records = records or []
- if local_redis().hexists(bots_domain, threebot_name):
- data = j.data.serializers.json.loads(local_redis().hget(bots_domain, threebot_name))
-
- if record_type in data:
- records.extend(data[record_type])
- data[record_type] = records
- local_redis().hset(bots_domain, threebot_name, j.data.serializers.json.dumps(data))
-
-
-
-def domain_register_a(name, domain, record_ip)
-
-
-
registers A domain in coredns (needs to be authoritative)
-
e.g: ahmed.bots.grid.tf
-
requires nameserver on bots.grid.tf (authoritative)
-- ahmed is threebot_name
-- bots_domain is bots.grid.tf
-
:param threebot_name: myhost
-:type threebot_name: str
-:param bots_domain: str, defaults to "grid.tf."
-:type bots_domain: str, optional
-:param record_ip: machine ip in ipv4 format
-:type record_ip: str
-
-Source code
-
def domain_register_a(name, domain, record_ip):
- """registers A domain in coredns (needs to be authoritative)
-
- e.g: ahmed.bots.grid.tf
-
- requires nameserver on bots.grid.tf (authoritative)
- - ahmed is threebot_name
- - bots_domain is bots.grid.tf
-
- :param threebot_name: myhost
- :type threebot_name: str
- :param bots_domain: str, defaults to "grid.tf."
- :type bots_domain: str, optional
- :param record_ip: machine ip in ipv4 format
- :type record_ip: str
- """
- if addr_check(record_ip):
- return domain_register(name, domain, record_type="a", records=[{"ip": record_ip}])
- else:
- raise j.exceptions.Value("invalid ip {record_ip}".format(**locals()))