unitysvc-services 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,352 @@
1
+ from enum import StrEnum
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+
7
+ class AccessMethodEnum(StrEnum):
8
+ http = "http"
9
+ websocket = "websocket"
10
+ grpc = "grpc"
11
+
12
+
13
+ class AuthMethodEnum(StrEnum):
14
+ api_key = "api_key"
15
+ oauth = "oauth"
16
+ jwt = "jwt"
17
+ bearer_token = "bearer_token"
18
+ basic_auth = "basic_auth"
19
+
20
+
21
+ class ContentFilterEnum(StrEnum):
22
+ adult = "adult"
23
+ violence = "violence"
24
+ hate_speech = "hate_speech"
25
+ profanity = "profanity"
26
+ pii = "pii" # Personally Identifiable Information
27
+
28
+
29
+ class DocumentContextEnum(StrEnum):
30
+ access_interface = "access_interface" # Documents belong to AccessInterface
31
+ service_definition = "service_definition" # Documents belong to ServiceDefinition
32
+ service_offering = "service_offering" # Documents belong to ServiceOffering
33
+ service_listing = "service_listing" # Documents belong to ServiceListing
34
+ user = "user" # can be for seller, subscriber, consumer
35
+
36
+
37
+ class DocumentCategoryEnum(StrEnum):
38
+ getting_started = "getting_started"
39
+ api_reference = "api_reference"
40
+ tutorials = "tutorials"
41
+ code_examples = "code_examples"
42
+ use_cases = "use_cases"
43
+ troubleshooting = "troubleshooting"
44
+ changelog = "changelog"
45
+ best_practices = "best_practices"
46
+ specification = "specification"
47
+ service_level_agreement = "service_level_agreement"
48
+ terms_of_service = "terms_of_service"
49
+ invoice = "invoice"
50
+ logo = "logo"
51
+ avatar = "avatar"
52
+ other = "other"
53
+
54
+
55
+ class MimeTypeEnum(StrEnum):
56
+ markdown = "markdown"
57
+ python = "python"
58
+ javascript = "javascript"
59
+ bash = "bash"
60
+ html = "html"
61
+ text = "text"
62
+ pdf = "pdf"
63
+ jpeg = "jpeg"
64
+ png = "png"
65
+ svg = "svg"
66
+ url = "url"
67
+
68
+
69
+ class InterfaceContextTypeEnum(StrEnum):
70
+ service_offering = "service_offering" # Pricing from upstream provider
71
+ service_listing = "service_listing" # Pricing shown to end users
72
+
73
+
74
+ class SellerTypeEnum(StrEnum):
75
+ individual = "individual"
76
+ organization = "organization"
77
+ partnership = "partnership"
78
+ corporation = "corporation"
79
+
80
+
81
+ class ListingStatusEnum(StrEnum):
82
+ # Not yet determined
83
+ unknown = "unknown"
84
+ # step 1: upstream is ready to be used
85
+ upstream_ready = "upstream_ready"
86
+ # step 2: downstream is ready, with proper routing, logging, and billing
87
+ downstream_ready = "downstream_ready"
88
+ # step 3: service is operationally ready (with proper documentation and initial
89
+ # performance metrics, and pricing strategy)
90
+ ready = "ready"
91
+ # step 4: service is in service
92
+ in_service = "in_service"
93
+ # step 5.1: service is deprecated from upstream
94
+ upstream_deprecated = "upstream_deprecated"
95
+ # step 5.2: service is no longer offered to users (due to business reasons)
96
+ deprecated = "deprecated"
97
+
98
+
99
+ class OveragePolicyEnum(StrEnum):
100
+ block = "block" # Block requests when quota exceeded
101
+ throttle = "throttle" # Reduce rate when quota exceeded
102
+ charge = "charge" # Allow with additional charges
103
+ queue = "queue" # Queue requests until quota resets
104
+
105
+
106
+ class PricingTypeEnum(StrEnum):
107
+ upstream = "upstream" # Pricing from upstream provider
108
+ user_facing = "user_facing" # Pricing shown to end users
109
+
110
+
111
+ class PricingUnitEnum(StrEnum):
112
+ one_million_tokens = "one_million_tokens"
113
+ one_second = "one_second"
114
+ image = "image"
115
+ step = "step"
116
+
117
+
118
+ class QuotaResetCycleEnum(StrEnum):
119
+ daily = "daily"
120
+ weekly = "weekly"
121
+ monthly = "monthly"
122
+ yearly = "yearly"
123
+
124
+
125
+ class RateLimitUnitEnum(StrEnum):
126
+ requests = "requests"
127
+ tokens = "tokens"
128
+ input_tokens = "input_tokens"
129
+ output_tokens = "output_tokens"
130
+ bytes = "bytes"
131
+ concurrent = "concurrent"
132
+
133
+
134
+ class RequestTransformEnum(StrEnum):
135
+ # https://docs.api7.ai/hub/proxy-rewrite
136
+ proxy_rewrite = "proxy_rewrite"
137
+ # https://docs.api7.ai/hub/body-transformer
138
+ body_transformer = "body_transformer"
139
+
140
+
141
+ class ServiceTypeEnum(StrEnum):
142
+ llm = "llm"
143
+ # generate embedding from texts
144
+ embedding = "embedding"
145
+ # generation of images from prompts
146
+ image_generation = "image_generation"
147
+ # streaming trancription needs websocket connection forwarding, and cannot
148
+ # be provided for now.
149
+ streaming_transcription = "streaming_transcription"
150
+ # prerecorded transcription
151
+ prerecorded_transcription = "prerecorded_transcription"
152
+ # prerecorded translation
153
+ prerecorded_translation = "prerecorded_translation"
154
+ # describe images
155
+ vision_language_model = "vision_language_model"
156
+ #
157
+ speech_to_text = "speech_to_text"
158
+ #
159
+ text_to_speech = "text_to_speech"
160
+ #
161
+ video_generation = "video_generation"
162
+ #
163
+ text_to_image = "text_to_image"
164
+ #
165
+ undetermined = "undetermined"
166
+ #
167
+ text_to_3d = "text_to_3d"
168
+
169
+
170
+ class SubscriptionStatusEnum(StrEnum):
171
+ active = "active"
172
+ cancelled = "cancelled"
173
+ expired = "expired"
174
+ pending = "pending"
175
+ trialing = "trialing"
176
+ failed = "failed"
177
+ paused = "paused"
178
+ incomplete = "incomplete"
179
+ incomplete_expired = "incomplete_expired"
180
+ unpaid = "unpaid"
181
+
182
+
183
+ class TagEnum(StrEnum):
184
+ """
185
+ Allowed enums, currently not enforced.
186
+ """
187
+
188
+ # Service requires users to provide their own API key for access.
189
+ byop = "byop"
190
+
191
+
192
+ class TimeWindowEnum(StrEnum):
193
+ second = "second"
194
+ minute = "minute"
195
+ hour = "hour"
196
+ day = "day"
197
+ month = "month"
198
+
199
+
200
+ class UpstreamStatusEnum(StrEnum):
201
+ # uploading (not ready)
202
+ uploading = "uploading"
203
+ # upstream is ready to be used
204
+ ready = "ready"
205
+ # service is deprecated from upstream
206
+ deprecated = "deprecated"
207
+
208
+
209
+ class Document(BaseModel):
210
+ model_config = ConfigDict(extra="forbid")
211
+
212
+ # fields that will be stored in backend database
213
+ #
214
+ title: str = Field(min_length=5, max_length=255, description="Document title")
215
+ description: str | None = Field(default=None, max_length=500, description="Document description")
216
+ mime_type: MimeTypeEnum = Field(description="Document MIME type")
217
+ version: str | None = Field(default=None, max_length=50, description="Document version")
218
+ category: DocumentCategoryEnum = Field(description="Document category for organization and filtering")
219
+ meta: dict[str, Any] | None = Field(
220
+ default=None,
221
+ description="JSON containing operation stats",
222
+ )
223
+ file_path: str | None = Field(
224
+ default=None,
225
+ max_length=1000,
226
+ description="Path to file to upload (mutually exclusive with external_url)",
227
+ )
228
+ external_url: str | None = Field(
229
+ default=None,
230
+ max_length=1000,
231
+ description="External URL for the document (mutually exclusive with object_key)",
232
+ )
233
+ sort_order: int = Field(default=0, description="Sort order within category")
234
+ is_active: bool = Field(default=True, description="Whether document is active")
235
+ is_public: bool = Field(
236
+ default=False,
237
+ description="Whether document is publicly accessible without authentication",
238
+ )
239
+
240
+
241
+ class RateLimit(BaseModel):
242
+ """Store rate limiting rules for services."""
243
+
244
+ model_config = ConfigDict(extra="forbid")
245
+
246
+ # Core rate limit definition
247
+ limit: int = Field(description="Maximum allowed in the time window")
248
+ unit: RateLimitUnitEnum = Field(description="What is being limited")
249
+ window: TimeWindowEnum = Field(description="Time window for the limit")
250
+
251
+ # Optional additional info
252
+ description: str | None = Field(default=None, max_length=255, description="Human-readable description")
253
+ burst_limit: int | None = Field(default=None, description="Short-term burst allowance")
254
+
255
+ # Status
256
+ is_active: bool = Field(default=True, description="Whether rate limit is active")
257
+
258
+
259
+ class ServiceConstraints(BaseModel):
260
+ model_config = ConfigDict(extra="forbid")
261
+
262
+ # Usage Quotas & Billing
263
+ monthly_quota: int | None = Field(default=None, description="Monthly usage quota (requests, tokens, etc.)")
264
+ daily_quota: int | None = Field(default=None, description="Daily usage quota (requests, tokens, etc.)")
265
+ quota_unit: RateLimitUnitEnum | None = Field(default=None, description="Unit for quota limits")
266
+ quota_reset_cycle: QuotaResetCycleEnum | None = Field(default=None, description="How often quotas reset")
267
+ overage_policy: OveragePolicyEnum | None = Field(default=None, description="What happens when quota is exceeded")
268
+
269
+ # Authentication & Security
270
+ auth_methods: list[AuthMethodEnum] | None = Field(default=None, description="Supported authentication methods")
271
+ ip_whitelist_required: bool | None = Field(default=None, description="Whether IP whitelisting is required")
272
+ tls_version_min: str | None = Field(default=None, description="Minimum TLS version required")
273
+
274
+ # Request/Response Constraints
275
+ max_request_size_bytes: int | None = Field(default=None, description="Maximum request payload size in bytes")
276
+ max_response_size_bytes: int | None = Field(default=None, description="Maximum response payload size in bytes")
277
+ timeout_seconds: int | None = Field(default=None, description="Request timeout in seconds")
278
+ max_batch_size: int | None = Field(default=None, description="Maximum number of items in batch requests")
279
+
280
+ # Content & Model Restrictions
281
+ content_filters: list[ContentFilterEnum] | None = Field(
282
+ default=None, description="Active content filtering policies"
283
+ )
284
+ input_languages: list[str] | None = Field(default=None, description="Supported input languages (ISO 639-1 codes)")
285
+ output_languages: list[str] | None = Field(default=None, description="Supported output languages (ISO 639-1 codes)")
286
+ max_context_length: int | None = Field(default=None, description="Maximum context length in tokens")
287
+ region_restrictions: list[str] | None = Field(
288
+ default=None, description="Geographic restrictions (ISO country codes)"
289
+ )
290
+
291
+ # Availability & SLA
292
+ uptime_sla_percent: float | None = Field(default=None, description="Uptime SLA percentage (e.g., 99.9)")
293
+ response_time_sla_ms: int | None = Field(default=None, description="Response time SLA in milliseconds")
294
+ maintenance_windows: list[str] | None = Field(default=None, description="Scheduled maintenance windows")
295
+
296
+ # Concurrency & Connection Limits
297
+ max_concurrent_requests: int | None = Field(default=None, description="Maximum concurrent requests allowed")
298
+ connection_timeout_seconds: int | None = Field(default=None, description="Connection timeout in seconds")
299
+ max_connections_per_ip: int | None = Field(default=None, description="Maximum connections per IP address")
300
+
301
+
302
+ class AccessInterface(BaseModel):
303
+ model_config = ConfigDict(extra="allow")
304
+
305
+ access_method: AccessMethodEnum = Field(default=AccessMethodEnum.http, description="Type of access method")
306
+
307
+ api_endpoint: str = Field(max_length=500, description="API endpoint URL")
308
+
309
+ api_key: str | None = Field(default=None, max_length=2000, description="API key if required")
310
+
311
+ name: str | None = Field(default=None, max_length=100, description="Interface name")
312
+
313
+ description: str | None = Field(default=None, max_length=500, description="Interface description")
314
+
315
+ request_transformer: dict[RequestTransformEnum, dict[str, Any]] | None = Field(
316
+ default=None, description="Request transformation configuration"
317
+ )
318
+
319
+ documents: list[Document] | None = Field(
320
+ default=None, description="List of documents associated with the interface"
321
+ )
322
+
323
+ rate_limits: list[RateLimit] | None = Field(
324
+ default=None,
325
+ description="Rate limit",
326
+ )
327
+ constraint: ServiceConstraints | None = Field(default=None, description="Service constraints and conditions")
328
+ is_active: bool = Field(default=True, description="Whether interface is active")
329
+ is_primary: bool = Field(default=False, description="Whether this is the primary interface")
330
+ sort_order: int = Field(default=0, description="Display order")
331
+
332
+
333
+ class Pricing(BaseModel):
334
+ model_config = ConfigDict(extra="forbid")
335
+
336
+ # Pricing tier name (Basic, Pro, Enterprise, etc.)
337
+ name: str | None = Field(default=None, description="Pricing tier name (e.g., Basic, Pro, Enterprise)")
338
+
339
+ description: str | None = Field(default=None, description="Pricing model description")
340
+
341
+ # Currency and description
342
+ currency: str | None = Field(default=None, description="Currency code (e.g., USD)")
343
+
344
+ unit: PricingUnitEnum = Field(description="Unit of pricing")
345
+
346
+ # Store price as JSON - flexible structure for different pricing models
347
+ price_data: dict[str, Any] = Field(
348
+ description="JSON containing price data (single price, tiered, usage-based, etc.)",
349
+ )
350
+
351
+ # Optional reference to upstream pricing
352
+ reference: str | None = Field(default=None, description="Reference URL to upstream pricing")
@@ -0,0 +1,72 @@
1
+ from datetime import datetime
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+ from unitysvc_services.models.base import (
7
+ AccessInterface,
8
+ Document,
9
+ ListingStatusEnum,
10
+ Pricing,
11
+ )
12
+
13
+
14
+ class ListingV1(BaseModel):
15
+ model_config = ConfigDict(extra="forbid")
16
+
17
+ #
18
+ # fields for business data collection and maintenance
19
+ #
20
+ schema_version: str = Field(default="listing_v1", description="Schema identifier", alias="schema")
21
+ time_created: datetime
22
+
23
+ #
24
+ # fields that will be stored in backend database
25
+ #
26
+ service_name: str | None = Field(
27
+ default=None,
28
+ description=(
29
+ "Name of the service (ServiceV1.name), optional if only one service is defined under the same directory."
30
+ ),
31
+ )
32
+
33
+ seller_name: str = Field(
34
+ description="Name of the seller offering this service listing"
35
+ )
36
+
37
+ # unique name for each provider, usually following upstream naming convention
38
+ # status of the service, public, deprecated etc
39
+ listing_status: ListingStatusEnum = Field(
40
+ default=ListingStatusEnum.unknown,
41
+ description="Operation status of the service",
42
+ )
43
+
44
+ #
45
+ # how to users access the service from upstream, which can include
46
+ # - endpoint
47
+ # - access_method
48
+ # - code_examples
49
+ # multiple access interfaces can be provided, for example, if the service
50
+ # is available through multiple interfaces or service groups
51
+ user_access_interfaces: list[AccessInterface] = Field(description="Dictionary of user access interfaces")
52
+
53
+ #
54
+ # how upstream charges for their services, which can include
55
+ # a list of pricing models
56
+ #
57
+ user_price: Pricing | None = Field(description="Dictionary of pricing information")
58
+
59
+ documents: list[Document] | None = Field(
60
+ default=None,
61
+ description="List of documents associated with the listing (e.g. service level agreements)",
62
+ )
63
+ #
64
+ # schema for accepting user parameters for the service
65
+ #
66
+ user_parameters_schema: dict[str, Any] | None = Field(
67
+ default=None, description="Dictionary of user parameters schema"
68
+ )
69
+
70
+ user_parameters_ui_schema: dict[str, Any] | None = Field(
71
+ default=None, description="Dictionary of user parameters UI schema"
72
+ )
@@ -0,0 +1,53 @@
1
+ from datetime import datetime
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, ConfigDict, EmailStr, Field, HttpUrl
5
+
6
+ from unitysvc_services.models.base import AccessInterface, Document
7
+
8
+
9
+ class ProviderV1(BaseModel):
10
+ model_config = ConfigDict(extra="forbid")
11
+
12
+ #
13
+ # fields for business data collection and maintenance
14
+ #
15
+ schema_version: str = Field(default="provider_v1", description="Schema identifier", alias="schema")
16
+ time_created: datetime
17
+ # how to automatically populate service data, if available
18
+ services_populator: dict[str, Any] | None = None
19
+ # parameters for accessing service provider, which typically
20
+ # include "api_endpoint" and "api_key"
21
+ provider_access_info: AccessInterface = Field(description="Dictionary of upstream access interface")
22
+ #
23
+ # fields that will be stored in backend database
24
+ #
25
+
26
+ # name of the provider should be the same as directory name
27
+ name: str
28
+
29
+ # this field is added for convenience. It will be converted to
30
+ # documents during importing.
31
+ logo: str | HttpUrl | None = None
32
+
33
+ # this field is added for convenience. It will be converted to
34
+ # documents during importing.
35
+ terms_of_service: None | str | HttpUrl = Field(
36
+ default=None,
37
+ description="Either a path to a .md file or a URL to terms of service",
38
+ )
39
+
40
+ documents: list[Document] | None = Field(
41
+ default=None,
42
+ description="List of documents associated with the provider (e.g. logo)",
43
+ )
44
+ #
45
+ # fields for business operation purposes, not stored in backend database
46
+ #
47
+
48
+ # internal business data, usually not expose to users, and may not store
49
+ # in database
50
+ description: str | None = None
51
+ homepage: HttpUrl
52
+ contact_email: EmailStr
53
+ secondary_contact_email: EmailStr | None = None
@@ -0,0 +1,110 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import BaseModel, ConfigDict, EmailStr, Field, HttpUrl
4
+
5
+ from unitysvc_services.models.base import Document, SellerTypeEnum
6
+
7
+
8
+ class SellerV1(BaseModel):
9
+ """
10
+ Seller information for marketplace sellers.
11
+
12
+ Each repository can only have one seller.json file at the root of the data directory.
13
+ """
14
+
15
+ model_config = ConfigDict(extra="forbid")
16
+
17
+ #
18
+ # fields for business data collection and maintenance
19
+ #
20
+ schema_version: str = Field(default="seller_v1", description="Schema identifier", alias="schema")
21
+ time_created: datetime
22
+
23
+ #
24
+ # fields that will be stored in backend database
25
+ #
26
+
27
+ # Seller name must be unique and URL-friendly (lowercase, hyphens)
28
+ name: str = Field(
29
+ description="Unique seller identifier (URL-friendly, e.g., 'acme-corp', 'john-doe')",
30
+ min_length=2,
31
+ max_length=100,
32
+ )
33
+
34
+ # Display name for UI
35
+ display_name: str | None = Field(
36
+ default=None,
37
+ max_length=200,
38
+ description="Human-readable seller name (e.g., 'ACME Corporation', 'John Doe')",
39
+ )
40
+
41
+ # Seller type
42
+ seller_type: SellerTypeEnum = Field(
43
+ default=SellerTypeEnum.individual,
44
+ description="Type of seller entity",
45
+ )
46
+
47
+ # Contact information
48
+ contact_email: EmailStr = Field(description="Primary contact email for the seller")
49
+
50
+ secondary_contact_email: EmailStr | None = Field(default=None, description="Secondary contact email")
51
+
52
+ # Account manager
53
+ account_manager: str | None = Field(
54
+ default=None,
55
+ max_length=100,
56
+ description="Email or username of the user managing this seller account",
57
+ )
58
+
59
+ homepage: HttpUrl | None = Field(default=None, description="Seller's homepage URL")
60
+
61
+ # Business information
62
+ description: str | None = Field(
63
+ default=None,
64
+ max_length=1000,
65
+ description="Brief description of the seller",
66
+ )
67
+
68
+ business_registration: str | None = Field(
69
+ default=None,
70
+ max_length=100,
71
+ description="Business registration number (if organization)",
72
+ )
73
+
74
+ tax_id: str | None = Field(
75
+ default=None,
76
+ max_length=100,
77
+ description="Tax identification number (EIN, VAT, etc.)",
78
+ )
79
+
80
+ # Stripe Connect integration
81
+ stripe_connect_id: str | None = Field(
82
+ default=None,
83
+ max_length=255,
84
+ description="Stripe Connect account ID for payment processing",
85
+ )
86
+
87
+ # Documents (logo, business docs, etc.)
88
+ # This field is added for convenience. It will be converted to
89
+ # documents during importing.
90
+ logo: str | HttpUrl | None = None
91
+
92
+ documents: list[Document] | None = Field(
93
+ default=None,
94
+ description="List of documents associated with the seller (e.g. business registration, tax documents)",
95
+ )
96
+
97
+ #
98
+ # fields for business operation purposes
99
+ #
100
+
101
+ # Status flags - these would typically be set by the backend
102
+ is_active: bool = Field(
103
+ default=True,
104
+ description="Whether the seller is active on the marketplace",
105
+ )
106
+
107
+ is_verified: bool = Field(
108
+ default=False,
109
+ description="Whether the seller has been verified (KYC/business verification)",
110
+ )
@@ -0,0 +1,80 @@
1
+ from datetime import datetime
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field, HttpUrl
5
+
6
+ from unitysvc_services.models.base import (
7
+ AccessInterface,
8
+ Document,
9
+ Pricing,
10
+ ServiceTypeEnum,
11
+ TagEnum,
12
+ UpstreamStatusEnum,
13
+ )
14
+
15
+
16
+ class ServiceV1(BaseModel):
17
+ model_config = ConfigDict(extra="forbid")
18
+
19
+ #
20
+ # fields for business data collection and maintenance
21
+ #
22
+ schema_version: str = Field(default="service_v1", description="Schema identifier", alias="schema")
23
+ time_created: datetime
24
+
25
+ #
26
+ # fields that will be stored in backend database
27
+ #
28
+ # unique name for each provider, usually following upstream naming convention
29
+ name: str
30
+ # type of service to group services
31
+ service_type: ServiceTypeEnum
32
+ # common display name for the service, allowing across provider linking
33
+ display_name: str
34
+ # version of the service, this, combined with display_name, allowing across provider linking
35
+ # of specific services, despite of provider internal naming conventions. Note that
36
+ # same display_name and version does not guarantee the same service (e.g. context window
37
+ # can be different)
38
+ version: str | None
39
+
40
+ # description of service, mandatory
41
+ description: str
42
+
43
+ # this field is added for convenience. It will be converted to
44
+ # documents during importing.
45
+ logo: str | HttpUrl | None = None
46
+
47
+ # Short elevator pitch or description for the service
48
+ tagline: str | None = None
49
+
50
+ # Tags for the service, e.g., bring your own API key
51
+ tags: list[TagEnum] | None = Field(
52
+ default=None,
53
+ description="List of tags for the service, e.g., bring your own API key",
54
+ )
55
+
56
+ # status of the service, public, deprecated etc
57
+ upstream_status: UpstreamStatusEnum = Field(
58
+ default=UpstreamStatusEnum.ready,
59
+ description="Status of the service from upstream service provider",
60
+ )
61
+
62
+ # static information from upstream, each service_type will have a
63
+ # set of mandatory fields
64
+ details: dict[str, Any] = Field(description="Dictionary of static features and information")
65
+
66
+ documents: list[Document] | None = Field(
67
+ default=None,
68
+ description="List of documents associated with the service (e.g. tech spec.)",
69
+ )
70
+ #
71
+ # how to access the service from upstream, which can include
72
+ # - endpoint
73
+ # - apikey
74
+ # - access_method
75
+ upstream_access_interface: AccessInterface = Field(description="Dictionary of upstream access interface")
76
+ #
77
+ # how upstream charges for their services, which can include
78
+ # a list of pricing models
79
+ #
80
+ upstream_price: Pricing | None = Field(description="List of pricing information")