Konstantinos Bairaktaris

Automate Localization With TX’s Python SDK

Python SDK

Following the release of our Transifex APIv3, today we are announcing the release of our Python API SDK.

This SDK will be part of the transifex-python package which also hosts our Transifex Native Python and Django SDKs. The import path of the API SDK is `transifex.api`,while the path of the Native SDKs will remain `transifex.native`.

{json:api}-based APIs and SDKs

As we discussed in the API blogpost, we chose to follow the guidelines of the {json:api} specification for our API. One of the main reasons for this is that this way, our API will be extremely predictable in what kind of requests it expects and what kind of responses it returns. So, the developer of an integration that understands the principles of {json:api} can be intimately familiar with the entirety of our API. And that should remain true even if they have worked with other {json:api} APIs or interacted with only a small part of ours.

Taking it to its logical conclusion, this would mean that a generic {json:api} SDK library (a library that helps you create SDKs) can be applied to the Transifex API with little to no modification. We looked into existing {json:api} SDK libraries to use in order to minimize the effort needed, but we decided to build our own in order to fully take advantage of the capabilities our API, and the {json:api} specification in general, offers.

Our own `transifex.api.jsonapi` SDK library is something that we are proud of and we believe that it can be a worthy contender to the existing libraries. Depending on the traction that our SDK gets, we may very well open-source it on its own (although you can still build your SDK by importing `transifex.api.jsonapi`). It offers an ORM-like interface that takes inspiration from Django’s ORM. The “actual” Transifex SDK is minimal, something that you can verify by looking at the source code, as almost the entire functionality is implemented within the SDK library.

One of the main advantages this approach offers us is that the SDK can adapt to future changes to our API with no changes at all! For example, we may introduce new fields or filters on an API endpoint and you will not have to update the SDK on your side to be able to use the updates in your integrations.

As a Transifex developer, I use this SDK almost every day. When I want to reproduce an issue reported by one of our users, I can quickly and intuitively set up any projects, resources, translations, etc. And I can also do that in our production environment, then test the reported behaviour before and after fixing the issue.

How it works

We start by downloading the SDK:

pip install transifex-python

Then we start a script:

from transifex.api import transifex_api transifex_api.setup(auth="...")

The `auth` argument to the `setup` method is the API token you have generated from the Transifex UI.

The SDK is meant to be used alongside our API v3 documentation. The first thing we need is to find our organization. Looking at the `/organizations` endpoint, we can see that there is a ‘slug’ we can take advantage of. So:

organization = transifex_api.Organization.filter(slug="my_organization")[0]
# or
organization = transifex_api.Organization.get(slug="my_organization")

(Note: `.all()` is used to ensure we iterate over all pages of a potentially paginated response; if we don’t expect there to be multiple pages, we can use `.list()`)

Looking at the documentation, we can see that:

  1. Organization objects have a relationship to their projects and
  2. The `/projects` endpoint has a `filter[slug]` filter that we can use

Using these facts, pinpointing a project becomes much easier:

project = organization.fetch('projects').get(slug="my_project")

Now, let’s inspect the project’s team. Looking at the API documentation, we can see that the payloads returned by `/projects` have a ‘team’ relationship:

team = project.fetch('team')
print(team.name)

Let’s create and assign a new team to our project (we once again cross-check with the API documentation to see which fields are available/required when creating a new team):

old_team = project.fetch('team')
new_team = transifex_api.Team.create(
    organization=organization,
    name="New team",
)
project.change('team', new_team)

(Note: calling `.fetch()` a second time will not make a new request to the server because the team is already fetched)

And delete the old team:

old_team.delete()

We just noticed that this project has the “Portuguese (Brazil)” language when we wanted the plain “Portuguese” language. Let’s fix this:

pt = transifex_api.Language.get(code="pt")
pt_BR = transifex_api.Language.get(code="pt_BR")
project.remove('languages', [pt_BR])
project.add('languages', [pt])

Finally, lets enable translation memory fill-up on our project:

project.save(translation_memory_fillup=True)

You can read more in our README. Interacting with any documented endpoint uses the exact same interface you have witnessed so far. You now know how to interact with the entirety of our API!

If you have any questions or you want to know more details, feel free to contact us or post on our Github repo.

 

Want to learn more about Transifex?

Give Transifex a try with our free 15 day trial, or connect with one of our team members for a personal demo.

Subscribe to
Becoming Global

Get localization news and best practices delivered to your inbox each month.