def _create_or_update_version(app_name, version, app_spec, try_update=True):
    # This has a race condition since the app could have been created or
    # published since we last looked.
    try:
        app_id = dxpy.api.app_new(app_spec)["id"]
        return app_id
    except dxpy.exceptions.DXAPIError as e:
        # TODO: detect this error more reliably
        if e.name == 'InvalidInput' and e.msg == 'Specified name and version conflict with an existing alias':
            print('App %s/%s already exists' % (app_spec["name"], version), file=sys.stderr)
            # The version number was already taken, so app/new doesn't work.
            # However, maybe it hasn't been published yet, so we might be able
            # to app-xxxx/update it.
            app_describe = dxpy.api.app_describe("app-" + app_name, alias=version)
            if app_describe.get("published", 0) > 0:
                return None
            return _update_version(app_name, version, app_spec, try_update=try_update)
        raise e
Load ComparableX509 certificate request.
dataset/ETHPy150Open dnanexus/dx-toolkit/src/python/dxpy/app_builder.py/_create_or_update_version--crossover with--dataset/ETHPy150Open letsencrypt/letsencrypt/acme/acme/test_util.py/load_comparable_csr