Usage

Authentication

As the API v3 documentation states:

To authenticate against the Travis CI API, you need an API access token generated by the Travis CI command line client:.

You are required to your API Token though their client or though one of those 2 links:

Initialization

There is 4 way to get started, but 1 gateway.

  1. Without any token.
  2. With a token from https://travis-ci.org (for public GitHub repositories)
  3. With a token from https://travis-ci.com (private GitHub repositories)
  4. With a token from an enterprise domain (e.g https://example.org/)

The gateway of all the mechanism is the TravisCI object. From there, you can start to navigate through the Travis CI API.

Without any token

from PyTravisCI import TravisCI

travis = TravisCI()

With a token from travis-ci.org

from PyTravisCI import TravisCI

travis = TravisCI(access_token="XYZ")

With a token from travis-ci.com

from PyTravisCI import defaults, TravisCI

travis = TravisCI(
    access_token="XYZ", access_point=defaults.access_points.PRIVATE
)

With a token from an enterprise domain

from PyTravisCI import defaults, TravisCI

travis = TravisCI(
    access_token="XYZ", access_point=defaults.access_points.ENTERPRISE.format("example.org")
)

Working with resource type objects

Although resource types have some nice method to help you, PyTravisCI provides you some other useful “helpers” to make it “easier”.

Access to information

Let’s read our information.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get our very own account information.
me = travis.get_user()

# We can read the JSON representation to get an idea of what we get.
print(me.json())

Now let’s say we want to read our id and login. We can do it like we will do with a dict.

my_id = me["id"]
my_login = me["login"]

Or by accessing the attribute

my_id = me.id
my_login = me.login

repr representation

If you print a resource type, you will get the following format.

<ResourceTypeClassName {... attributes ...} />

dict representation

You can at anytime get the dict representation of a resource type object.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3})

# We can now get the dict representation of our object.
# The .dict() method is actually an alias to .to_dict()!
print(my_repositories.dict())

JSON representation

You can at anytime get the JSON representation of a representation of a resource type object.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3})

# We can now get the dict representation of our object.
# The .json() method is actually an alias to .to_json()!
print(my_repositories.json())

Loop over collection of resources

Most of time, we may work with single entries or resources. But while working with a collection of resource, you may want to loop over them.

Guess what ? You can do it here too!

Warning

If the current resource type is not a collection a NotImplementedError will be raised.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3})

for repository in my_repositories:
    print(repository.json())

Comparison of resource types

You can easily compare 2 resource types object by checking if x == y. Where x and y are 2 resource type objects.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get a single repository
my_repo = travis.get_repository("funilrys/PyTravisCI")

# In this example because it is a collection we can directly access
# a member of the collection through its position.
# Or (most of time) you will have an attribute which held them.
#
# As presented here, we are accessing the same object in 2 different way.
wanted_job = my_repo.get_builds().builds[0].jobs[0]
wanted_job2 = my_repo.get_builds()[0].jobs[0]

assert wanted_job == wanted_job2

Handling incomplete or minimal representation of a resource type

Most of the time, Travis CI give us incomplete attributes which represents a resource type but in its minimal representation. With PyTravisCI you can directly get the complete representation directly.

Let’s take our previous example.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get a single repository
my_repo = travis.get_repository("funilrys/PyTravisCI")

# In this example because it is a collection we can directly access
# a member of the collection through its position.
# Or (most of time) you will have an attribute which held them.
#
# As presented here, we are accessing the same object in 2 different way.

# Both variables are minimal representation of the same job.
wanted_job = my_repo.get_builds().builds[0].jobs[0]
wanted_job2 = my_repo.get_builds()[0].jobs[0]

assert wanted_job == wanted_job2

if wanted_job2.is_incomplete():
    print(wanted_job.json())  # incomplete representation
    print("*" * 100)
    print(wanted_job2.get_complete().json())  # complete/standard representation

Next page of a resource type

Most of the times, you will have to play with the pagging system of the Travis CI API. We made it a bit simplier :-).

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3})

while True:
    for repository in my_repositories:
        print(repository.json())

    if my_repositories.has_next_page():
        my_repositories = my_repositories.next_page()
        continue
    break

Last page of a resource type

You can get the last page of a resource type too.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3}).last_page()

for repository in my_repositories:
    print(repository.json())

First page of a resource type

Sometime you are in a middle of a loop but for whatever reason, you want to go back to the first page. It’s possible too!

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3}).last_page()

while True:
    funilrys_repo_found = False

    for repository in my_repositories:
        print(repository.json())
        if "funilrys" in repository.slug:
            funilrys_repo_found = True

    if not funilrys_repo_found:
        my_repositories = my_repositories.next_page()
        continue
    break

# Now we work from the first page :-)
my_repositories = my_repositories.first_page()

Previous page of a resource type

Sometime you want to loop backwards :-).

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the list of repositories we have access to.
# Note: we limit to 3 because we have much more!
my_repositories = travis.get_repositories(params={"limit": 3}).last_page()

while True:
    for repository in my_repositories:
        print(repository.json())

    if my_repositories.has_previous_page():
        my_repositories = my_repositories.previous_page()
        continue
    break

Examples

You are invited to look at the resource types objects in order to get the method and attributes you look for.

In this section we present some example which may be asked a lot in issues. If we are missing some or if you have some questions, let me know per issue!

Warning

This section may be unuseful if you don’t know how to interact with resource type objects.

Information of the current user

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the current user information.
me = travis.get_user()

print(me.json())

Repositories of the current user

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the initial list of Repositories
repositories = travis.repositoris()

while True:
    # We loop until there is no more page to navigate.

    for repository in repositories:
        print(repository.json())

    if repositories.has_next_page():
        repositories = repositories.next_page()
        continue
    break

Organizations of the current user

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the jobs.
organizations = travis.get_organizations()

while True:
    # We loop until there is no more page to navigate.

    for organization in organizations:
        print(organization.json())

    if organizations.has_next_page():
        organizations = organizations.next_page()
        continue
    break

Active builds of the current user

Note

Active builds are build which are builds which have the state pending or started.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the current user information.
me = travis.get_user()

# We can now get the list of active builds.
active_builds = me.get_active()

while True:
    # We loop until there is no more page to navigate.

    for active_build in active_builds:
        print(active_build.json())

    if active_build.has_next_page():
        active_builds = active_builds.next_page()
        continue
    break

Builds of the current user

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the builds.
builds = travis.get_builds()

while True:
    # We loop until there is no more page to navigate.

    for build in builds:
        print(build.json())

    if builds.has_next_page():
        builds = builds.next_page()
        continue
    break

Jobs of the current user

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the jobs.
jobs = travis.get_jobs()

while True:
    # We loop until there is no more page to navigate.

    for job in jobs:
        print(job.json())

    if jobs.has_next_page():
        jobs = jobs.next_page()
        continue
    break

Restart the last build of a repository

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# We get the repository that interests us.
repository = travis.get_repository("funilrys/PyTravisCI")
# We get the build that interrest us (the latest one is always the first one).
build = repository.get_builds()[0]

try:
    build.restart()
except PyTravisCI.exceptions.BuildAlreadyStarted:
    # We really want to start so, we cancel it first.
    build.cancel()
    time.sleep(0.5)
    build.restart()

while build.is_active(sync=True):
    print("Build is running...")

    time.sleep(5)

print("Build finished!")

Lint a configuration file

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

with open(".travis.yml", "r") as file_stream:
    for index, warning in enumerate(travis.lint(file_stream)):
        if index > 0:
            print("*" * 100)

        print(
            f"{index + 1}. WARNING ({warning.warning_type}):\n"
            f"MESSAGE:\n\n{warning.message}\n\n"
        )

Create a new (build) request

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# Let's get the repository to work with.
repository = travis.get_repository("funilrys/PyTravisCI")

# Let's create a new request.
print(
    repository.create_request(
        "Hello, this request was created with PyTravisCI", "master"
    ).json()
)

Encrypt global environment variables for our configuration files

Travis allow us to directly give is a new environment variable. But we may want our environment variable to be encrypted into our configuration file.

Here is an example which show you how to get the encrypted string to put into your configuration file.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# Let's get the repository we want to work with.
repository = travis.get_repository("funilrys/PyTravisCI")

# This is what we are going to encrypt.
# one decrypted by TravisCI it will produces:
#
#   $ export HELLO=[secure]
#   $ export WORLD=[secure]
#
env_vars = {"HELLO": "world", "WORLD": "hello"}

# We now encrypt the shell environment variable:
#   HELLO=world
encrypte_vars = repository.encrypt_env_var(env_vars)

print(
    "Please append the following into the global environment variables "
    "section of your configuration file:"
)

for encrypted_var in encrypte_vars:
    print(f"- secure: \"{encrypted_var['secure']}\"\n\n")

Encrypt file

You may want to encrypt a file for a repository. This is what we will do in this example.

In this example, we have an off git file which is called id_rsa. We want to use it in our build process, so we will encrypt it into id_rsa.enc which will be then pushed to the repository.

PyTravisCI can generate the id_rsa.enc file for you but you will have to manually write the command to decrypt it. But don’t be stressed out, PyTravisCI will give you the command to run.

Here is an example which show you how to get help with the encryption of secret files.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# Let's get the repository we want to work with.
repository = travis.get_repository("funilrys/PyTravisCI")

with open("id_rsa", "rb") as secret_file, open(
    "id_rsa.enc", "wb"
) as encrypted_secret_file:

    information = repository.encrypt_file(secret_file, encrypted_secret_file)

    print(
        "Please append the following into the script section of "
        "your configuration file:\n\n"
        f"{information['command']}"
    )

Encrypt secrets

You may need to encrypt your/a password that you need to write into your configuration file for the deployment. This is what we will do in this example.

from PyTravisCI import TravisCI

# We initiate our "communication" object.
travis = TravisCI(acces_token="XYZ")

# Let's get the repository we want to work with.
repository = travis.get_repository("funilrys/PyTravisCI")

# Let's get our password :-)
password = "HeLlOW0rLd!"

# Let's encrypt our passowrd
encrypted_password = repository.encrypt_secrets([password])[0]

print(f'Here is your encrypted password:\n\n"{encrypted_password}"')