Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ml_model_packages.rb « api « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8a7a8fc9525e4d11e9e903d4f734e204094f04d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# frozen_string_literal: true

module API
  class MlModelPackages < ::API::Base
    include APIGuard
    include ::API::Helpers::Authentication

    ML_MODEL_PACKAGES_REQUIREMENTS = {
      model_name: API::NO_SLASH_URL_PART_REGEX,
      file_name: API::NO_SLASH_URL_PART_REGEX
    }.freeze

    ALLOWED_STATUSES = %w[default hidden].freeze

    feature_category :mlops
    urgency :low

    after_validation do
      require_packages_enabled!
      authenticate_non_get!

      not_found! unless can?(current_user, :read_model_registry, user_project)
    end

    authenticate_with do |accept|
      accept.token_types(:personal_access_token, :deploy_token, :job_token)
            .sent_through(:http_token)
    end

    helpers do
      include ::API::Helpers::PackagesHelpers
      include ::API::Helpers::Packages::BasicAuthHelpers

      def project
        authorized_user_project
      end

      def max_file_size_exceeded?
        project.actual_limits.exceeded?(:ml_model_max_file_size, params[:file].size)
      end
    end

    params do
      requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
    end

    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      namespace ':id/packages/ml_models' do
        params do
          requires :model_name, type: String, desc: 'Model name', regexp: Gitlab::Regex.ml_model_name_regex,
            file_path: true
          requires :model_version, type: String, desc: 'Model version',
            regexp: Gitlab::Regex.semver_regex
          requires :file_name, type: String, desc: 'Package file name',
            regexp: Gitlab::Regex.ml_model_file_name_regex, file_path: true
          optional :status, type: String, values: ALLOWED_STATUSES, desc: 'Package status'
        end
        namespace ':model_name/*model_version/:file_name', requirements: ML_MODEL_PACKAGES_REQUIREMENTS do
          desc 'Workhorse authorize model package file' do
            detail 'Introduced in GitLab 16.1'
            success code: 200
            failure [
              { code: 401, message: 'Unauthorized' },
              { code: 403, message: 'Forbidden' },
              { code: 404, message: 'Not Found' }
            ]
            tags %w[ml_model_registry]
          end
          put 'authorize' do
            authorize_workhorse!(subject: project, maximum_size: project.actual_limits.ml_model_max_file_size)
          end

          desc 'Workhorse upload model package file' do
            detail 'Introduced in GitLab 16.2'
            success code: 201
            failure [
              { code: 401, message: 'Unauthorized' },
              { code: 403, message: 'Forbidden' },
              { code: 404, message: 'Not Found' }
            ]
            tags %w[ml_model_registry]
          end
          params do
            requires :file,
              type: ::API::Validations::Types::WorkhorseFile,
              desc: 'The package file to be published (generated by Multipart middleware)',
              documentation: { type: 'file' }
          end
          put do
            authorize_upload!(project)

            bad_request!('File is too large') if max_file_size_exceeded?

            create_package_file_params = declared(params).merge(
              build: current_authenticated_job,
              package_name: params[:model_name],
              package_version: params[:model_version]
            )

            package_file = ::Packages::MlModel::CreatePackageFileService
                             .new(project, current_user, create_package_file_params)
                             .execute

            bad_request!('Package creation failed') unless package_file

            created!
          rescue ObjectStorage::RemoteStoreError => e
            Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: project.id })

            forbidden!
          end

          desc 'Download an ml_model package file' do
            detail 'This feature was introduced in GitLab 16.2'
            success code: 200
            failure [
              { code: 401, message: 'Unauthorized' },
              { code: 403, message: 'Forbidden' },
              { code: 404, message: 'Not Found' }
            ]
            tags %w[ml_model_registry]
          end
          get do
            authorize_read_package!(project)

            package = ::Packages::MlModel::PackageFinder.new(project)
                                                        .execute!(params[:model_name], params[:model_version])
            package_file = ::Packages::PackageFileFinder.new(package, params[:file_name]).execute!

            present_package_file!(package_file)
          end
        end
      end
    end
  end
end