Skip to content

2.026.23

Latest

Choose a tag to compare

@noliveleger noliveleger released this 16 Jun 20:49
· 47 commits to main since this release

What's changed

Features (10)
  • accountSettings: add UI for token regeneration (#7125)

    Allow regenerating the API Key (token) in the "Security" section of the
    "Account Settings" UI.

  • asset: add created by to API (#7094)

    Add created_by to the asset API responses.

    Update the asset list and detail endpoints with a new created_by field
    containing the username of the asset's creator.

  • auth: environment internal endpoint openapi docs (#6978)

    Added /environment endpoint to the OpenAPI docs

    Created EnvironmentResponseSerializer (along with SocialAppSerializer
    and MetadataFieldSerializer) to explicitly type out all configuration
    properties. Added markdown documentation describing what the endpoint
    provides. The view get() method was then decorated with @extend_schema
    to formally document the endpoint using Kobo's standardized
    open_api_200_ok_response format, and added APIV2Versioning so the V2
    schema generator picks it up.

  • bulkProcessing: mark in progress cells (#7055)

    Marks Project → Data → Table cells as in progress when a bulk action is
    undergoing. This change is hidden behind a feature flag.

  • bulkProcessing: dismissible info banner (#7092)

    On the Data Table, we show a dismissible info banner when bulk
    processing is actively running and at least one active job was started
    by a different user, so data changes are easier to anticipate. This is
    hidden behind feature flag.

  • dataTable: add processing columns (#7065)

    Display transcription/translation columns even if there is no data, but
    bulk processes are in progress. This change is part of incomplete
    feature, thus it is hidden behind a feature flag.

  • formSummary: always display extra metadata fields in summary (#7070)

    Summary now displays extra metadata fields even with the value is null
    or empty

  • frontend: create a reflux to react-query (orval) bridge (#7040)

  • nlp: implement Google API US/EU region routing for Speech-to-Text and Translation (#7128)

    This PR implements the server-wide Google ASR/MT location setting to
    enforce strict EU data residency or utilize global US infrastructure for
    Speech-to-Text (v2) and Translation (v3) APIs.

    Following the parallel switch to Google Cloud Speech-to-Text v2 and
    Translation v3, the previous ASR/MT region control setting (from
    ) was no longer functional. This PR re-establishes the
    server-wide US/EU location toggle and ensures requests are routed to the
    correct regional or global endpoints based on that configuration.

    Speech-to-Text (ASR) Updates:

    • The Google location is dynamically set to us or eu depending on
      the server-wide ASR_MT_GOOGLE_REGION setting.

    Translation (MT) Updates:

    • EU traffic is explicitly routed through the dedicated
      translate-eu.googleapis.com multi-regional gateway and processed in
      europe-west1. This guarantees that TLS termination, processing, and
      data-in-transit remain entirely within European borders.
    • US traffic is routed through translate-us.googleapis.com +
      us-west1.

    Constance setting:

    • Consolidated the legacy ASR_MT_GOOGLE_TRANSLATION_LOCATION setting
      (which tracked granular locations like us-central1 or europe-west1)
      into a new ASR_MT_GOOGLE_REGION Constance setting that provides a
      straightforward US or EU toggle.

    Region code fallback fix (pre-existing bug):

    • TranscriptionService.get_language_code() and get_configuration()
      previously raised LanguageNotSupported for any region code not
      explicitly listed in the database (e.g. fr-BE, de-AT). The check
      language_set.filter(code='fr-BE') always returned false because
      fr-BE is a region code, not a language code.
    • Fixed: both methods now extract the parent language code (fr from
      fr-BE) as a fallback. If the parent language is supported, the
      original region code is passed through to Google STT unchanged, allowing
      it to apply the best available model for that regional variant.
  • nlp: ensure maximum language support with per-language STT routing and GLOBAL/EU toggle (#7154)

    Extends the Google ASR/MT location handling from
    kpi#7128 to support
    every language Google offers. Instead of a fixed us/eu endpoint for
    all languages, the code now routes each language to whichever Google
    endpoint hosts its best available model. A new GLOBAL/EU Constance
    toggle replaces the old US/EU toggle: GLOBAL (default) uses
    per-language routing for maximum coverage; EU restricts all processing
    to EU-hosted endpoints for data residency compliance.

    kpi#7128 re-implemented
    the server-wide Google ASR/MT region setting (ASR_MT_GOOGLE_REGION)
    and simplified routing to use a single fixed location: us for all
    languages on non-EU servers and eu on EU servers.

    However, this caused 24 languages to lose ASR support, languages like
    Irish, Belarusian, Bosnian, and Somali that only have chirp_2 model
    support in specific Google sub-regions (us-central1, europe-west4)
    and no model at all in the us/eu multi-region endpoints.

    Because we cannot lose support for these 24 languages, we decided to
    implement the following approach instead:

    1. Global mode (default): Support every language that Google supports by
      routing each language to the endpoint that provides the best available
      model.
    2. EU mode: Use the best available model within EU-hosted endpoints
      only. Languages that are not available in any EU endpoint are considered
      unsupported on EU servers.

    In GLOBAL mode, the code reads location_code per language from the
    database (populated by the language spreadsheet, which stores the
    correct global location for each model). In EU mode, the code overrides
    the DB location at runtime using the table above via
    EU_LOCATION_BY_MODEL in locations.py.

Bug Fixes (4)
  • assets: fix deletion of projects with long names (#7147)

    Fixes a bug that was causing errors when users tried to delete a project
    with a particularly long name.

  • frontend: ensure proper hash navigation in few components (#6999)

    Clicking the app logo, the "Back to REST Services" button, or the "See
    plans" link no longer reloads the whole page.

  • languages: correct Orval-generated types for language services fields and LanguagesListParams (#7067)

    This PR corrects two OpenAPI schema inaccuracies in the language
    endpoints that caused incorrect Orval-generated TypeScript types for the
    frontend.

    This PR addresses two schema issues reported by the frontend against the
    language API endpoints.

    Issue 1: Incorrect schema for transcription_services /
    translation_services on the retrieve endpoint

    The list (/api/v2/languages/) and retrieve
    (/api/v2/languages/{code}/) endpoints return different shapes for the
    services fields, but both serializers were annotated with the same
    @extend_schema_field(ServicesField), causing drf-spectacular to emit
    one schema for both, which matched only the list endpoint. This led
    Orval to generate an incorrect array type for the retrieve endpoint's
    response.

    This is resolved by introducing a dedicated ServicesDetailField marker
    class and a corresponding ServicesDetailFieldExtension that emits the
    correct nested-object schema ({ [serviceCode]: { [regionCode]: string } }).

    LanguageSerializer (retrieve) is updated to use ServicesDetailField,
    while LanguageListSerializer (list) continues to use the existing
    ServicesField.

    Issue 2: Missing q query parameter in LanguagesListParams

    The LanguageViewSet relied on BaseViewSet's SearchFilter backend
    to handle the q parameter at runtime, but drf-spectacular requires
    explicit OpenApiParameter declarations to include query params in the
    schema. As a result, q was absent from the generated
    LanguagesListParams type, forcing the frontend to cast hook calls with
    as any. This is resolved by adding an explicit
    OpenApiParameter(name='q', ...) declaration to the list action
    schema, consistent with the pattern already used in
    TranscriptionServiceViewSet.

  • qual: export qual questions correctly (#7124)

    Fixes the qualitative manual multiple select data export

    The one hot data export for manual qualitative multiple select data was
    fixed on formpack.
    In import_export_task.py, the
    SubmissionExportTaskBase.get_export_object we pass for_output=True
    down to get_submissions in order to resolve the choice UUIDs into
    their corresponding human-readable labels. We have also added _uuid
    and meta/rootUuid to the additional_fields list in
    _get_fields_and_groups() to retrieve the qualitative payload
    correctly.

Documentation (1)
  • Add DPG Badge to README (#7071)

    This PR includes the new DPG badge in the README file, following the
    guide
    ,
    and links to KoboToolbox's new profile page on the DPG
    Registry
    .

Continous Integration (1)
  • openapi: fail CI job on drf-spectacular error (#7097)
Refactor (10)
  • formLanguagesManager: improve flaky tests (#7091)

    Improve form language manager Storybook tests

  • frontend: drop react-debounced-input in favor of mantine based component (#7019)

  • frontend: migrate Languages/Translations modal to Mantine and react-query (#7042)

    Migrates the project languages and translations modal interface to Mantine components and react-query

  • frontend: remove react-tagsinput in favor of Mantine-powered in-house component (#7089)

    Project and library tag inputs now use Kobo’s Mantine-based TagsInput,
    which keeps tag editing working while removing the legacy
    react-tagsinput dependency.

  • languageSelector: update and replace old language selector (#7039)

    Update old language selector into a new component

  • library: mantineify upload modal (#7101)

  • libraryAssetForm: remove mixins (#7068)

  • libraryAssetForm: migrate to TypeScript (#7069)

  • libraryAssetForm: change component to functional and use proper metadata (#7072)

    Library asset create and edit forms now fully honor instance-configured
    project metadata fields, and the select controls used in that form were
    modernized and stabilized (new shared Select and MultiSelect wrappers,
    Mantine input migration, shared theme base styles, and UI parity fixes).

    Until now, the create/edit form for library templates and collections
    rendered a fixed set of metadata fields (description, sector, country)
    regardless of what the instance had configured. If an admin disabled one
    of those, it still showed up; if they enabled operational_purpose,
    collects_pii, or any custom extra metadata field, it was nowhere to be
    found. The form now behaves the same way Project Settings already does
    and renders exactly the fields the environment exposes.

  • regionSelector: update and replace old region selector (#7073)

    Updates the region selector UI in the automated
    transcription/translation step

Chores (4)
  • api: [breaking] remove all legacy v1 API endpoints (#7098)

    The legacy /api/v1/ API has been fully removed. Requests to removed
    endpoints now receive an HTTP 410 Gone response with a link to the
    migration guide.

    All remaining /api/v1/ endpoints have been removed:

    • /api/v1/user, /api/v1/users
    • /api/v1/notes
    • /api/v1/forms, /api/v1/formlist
    • /api/v1/data (submissions, metadata, media)
    • /api/v1/briefcase
    • KPI v1 endpoints

    Any request to a removed endpoint returns HTTP 410 Gone (HTML, JSON,
    XML depending on Accept header) with a link to the migration article:
    https://support.kobotoolbox.org/migrating_api.html

  • deps: remove temporary Python pins (#6829)

  • github: update PR checklist (#7100)

  • security: add vulnerability reporting policy (#7082)

    Add SECURITY.md file with link to KoboToolbox Vulnerability Reporting
    Policy.


Full Changelog: https://github.com/kobotoolbox/kpi/compare/2.026.21c..2.026.23