Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/apic-extension/azext_apic_extension/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@
text: |
az apic api register -g api-center-test -n contosoeuap --api-location "examples/cli-examples/spec-examples/openai.json" --environment-id public
az apic api register -g api-center-test -n contosoeuap --api-location "examples/cli-examples/spec-examples/openai.yml" --environment-id public
- name: Register api by providing spec url.
text: |
az apic api register -g api-center-test -n contosoeuap --api-location "https://petstore.swagger.io/v2/swagger.json" --environment-id public
az apic api register -g api-center-test -n contosoeuap --api-location "https://petstore.swagger.io/v2/swagger.yaml" --environment-id public
"""
69 changes: 49 additions & 20 deletions src/apic-extension/azext_apic_extension/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from .command_patches import ExportAPIDefinitionExtension
from .command_patches import ExportMetadataExtension

from azure.cli.core.azclierror import InvalidArgumentValueError

logger = get_logger(__name__)


Expand Down Expand Up @@ -162,26 +164,53 @@ def register_apic(cmd, api_location, resource_group, service_name, environment_i
# Load the JSON file
if api_location:

# TODO Future Confirm its a file and not link
with open(str(api_location), 'rb') as f:
rawdata = f.read()
result = chardet.detect(rawdata)
encoding = result['encoding']

# TODO - read other file types later
value = None
if str(api_location).endswith('.yaml') or str(api_location).endswith('.yml'):
with open(str(api_location), 'r', encoding=encoding) as f:
content = f.read()
data = yaml.safe_load(content)
if data:
value = content
if (str(api_location).endswith('.json')):
with open(str(api_location), 'r', encoding=encoding) as f:
content = f.read()
data = json.loads(content)
if data:
value = content
custom_format = 'inline'
# Read the spec content from URL
if str(api_location).startswith('https://') or str(api_location).startswith('http://'):
try:
# Fetch the content from the URL
response = requests.get(api_location)
# Raise an error for bad status codes
response.raise_for_status()
# Try to parse the content as JSON
try:
data = json.loads(response.content)
except json.JSONDecodeError:
try:
# If JSON parsing fails, try to parse as YAML
data = yaml.safe_load(response.content)
except yaml.YAMLError as e:
data = None
value = None
raise InvalidArgumentValueError(error_msg=f"Error parsing data from {api_location}: {e}")
# sys.exit(-1)
# If we could parse the content(json or yaml), set format to link
value = str(api_location) if data else None
custom_format = 'link' if data else 'inline'
except requests.exceptions.RequestException as e:
data = None
value = None
raise InvalidArgumentValueError(error_msg=f"Error fetching data from invalid url {api_location}: {e}")
# sys.exit(-1)
else:
# Confirm its a file and not link
with open(str(api_location), 'rb') as f:
rawdata = f.read()
result = chardet.detect(rawdata)
encoding = result['encoding']

# TODO - read other file types later
if str(api_location).endswith('.yaml') or str(api_location).endswith('.yml'):
with open(str(api_location), 'r', encoding=encoding) as f:
content = f.read()
data = yaml.safe_load(content)
value = content if data else None
if (str(api_location).endswith('.json')):
with open(str(api_location), 'r', encoding=encoding) as f:
content = f.read()
data = json.loads(content)
value = content if data else None

# If we could not read the file, return error
if value is None:
Expand Down Expand Up @@ -315,7 +344,7 @@ def register_apic(cmd, api_location, resource_group, service_name, environment_i
'api_id': extracted_api_name,
'version_id': extracted_api_version,
'definition_id': extracted_definition_name,
'format': 'inline',
'format': custom_format,
'specification': specification_details, # TODO write the correct spec object
'value': value
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.3
method: GET
uri: https://github.com/
response:
body:
string: '!!! The response body has been omitted from the recording because it
is larger than 128 KB. It will be replaced with blank content of 254684 bytes
while replay. <CTRL-REPLACE>254684'
headers:
accept-ranges:
- bytes
cache-control:
- max-age=0, private, must-revalidate
content-language:
- en-US
content-length:
- '181'
content-security-policy:
- 'default-src ''none''; base-uri ''self''; child-src github.com/assets-cdn/worker/
github.com/webpack/ github.com/assets/ gist.github.com/assets-cdn/worker/;
connect-src ''self'' uploads.github.com www.githubstatus.com collector.github.com
raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com
github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com
*.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com
objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com
proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com
wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/
productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/
productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/
productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/
productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/
productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/
productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/
productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/
productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/
productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/
productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com
github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com
wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com
api.business.githubcopilot.com api.enterprise.githubcopilot.com github.githubassets.com
edge.fullstory.com rs.fullstory.com; font-src github.githubassets.com; form-action
''self'' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com;
frame-ancestors ''none''; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com
www.youtube-nocookie.com; img-src ''self'' data: blob: github.githubassets.com
media.githubusercontent.com camo.githubusercontent.com identicons.github.com
avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com
objects.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/
private-user-images.githubusercontent.com opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com
customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com
*.githubusercontent.com; manifest-src ''self''; media-src github.com user-images.githubusercontent.com/
secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com
github-production-user-asset-6210df.s3.amazonaws.com gist.github.com github.githubassets.com;
script-src github.githubassets.com; style-src ''unsafe-inline'' github.githubassets.com;
upgrade-insecure-requests; worker-src github.com/assets-cdn/worker/ github.com/webpack/
github.com/assets/ gist.github.com/assets-cdn/worker/'
content-type:
- text/html; charset=utf-8
date:
- Tue, 15 Oct 2024 04:01:12 GMT
etag:
- W/"2a20e14cbb76e542f3c5fed75a897deb"
referrer-policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
server:
- GitHub.com
set-cookie:
- _gh_sess=nDe4UkSl89r%2BcpkpALiHWruZQSCE0K7Fv4fZdUJ16N4E1RiBG7xxX7sfwTTFgEBKMq3qRcEnxXvS3tZOl5yHbg1o2Uda3WqjBs4TNl7cYJI7F6QT5eyX%2FtSiHQYzoxuAyhq5e%2F%2Bouf17OSFst%2FoFYupJtDycyzraeIzFF7CY6%2FLMz8AvqcXpf%2FQBM2C0pU%2FZQDG%2F9pdSzk6xumiDwggGAJ1WhMgHSE%2FPWlQIQoPfh%2FF%2FOwIOs7NWfq6d5zkw0tcAbzNO%2Fo5x1oL1C7EY88z2%2Bg%3D%3D--DX1tQfpx6VemsBsP--fkxfh8oqGwFOgJFUsVzA5Q%3D%3D;
Path=/; HttpOnly; Secure; SameSite=Lax
- _octo=GH1.1.1313912529.1728964875; Path=/; Domain=github.com; Expires=Wed,
15 Oct 2025 04:01:15 GMT; Secure; SameSite=Lax
- logged_in=no; Path=/; Domain=github.com; Expires=Wed, 15 Oct 2025 04:01:15
GMT; HttpOnly; Secure; SameSite=Lax
strict-transport-security:
- max-age=31536000; includeSubdomains; preload
transfer-encoding:
- chunked
vary:
- X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Language, Accept-Encoding,
Accept, X-Requested-With
x-content-type-options:
- nosniff
x-frame-options:
- deny
x-github-request-id:
- 0806:21A5DE:29131BD:2D8EF81:670DE90B
x-xss-protection:
- '0'
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
CommandName:
- apic api show
Connection:
- keep-alive
ParameterSetName:
- -g -n --api-id
User-Agent:
- AZURECLI/2.63.0 azsdk-python-core/1.28.0 Python/3.11.9 (Windows-10-10.0.22631-SP0)
method: GET
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clirg000001/providers/Microsoft.ApiCenter/services/clitest000002/workspaces/default/apis/swaggerpetstore?api-version=2024-03-01
response:
body:
string: '{"code":"404"}'
headers:
api-supported-versions:
- 2023-07-01-preview, 2024-03-01, 2024-03-15-preview
cache-control:
- no-cache
content-length:
- '14'
content-type:
- application/json; charset=utf-8
date:
- Tue, 15 Oct 2024 04:01:16 GMT
expires:
- '-1'
pragma:
- no-cache
strict-transport-security:
- max-age=31536000; includeSubDomains
vary:
- Accept-Encoding
x-cache:
- CONFIG_NOCACHE
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-global-reads:
- '16499'
x-msedge-ref:
- 'Ref A: F157DB4EBD6E442D94239BD1D1EBFE1A Ref B: MAA201060513023 Ref C: 2024-10-15T04:01:15Z'
x-powered-by:
- ASP.NET
status:
code: 404
message: Not Found
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.32.3
method: GET
uri: https://github.com/invalidrepo
response:
body:
string: Not Found
headers:
cache-control:
- no-cache
content-length:
- '9'
content-security-policy:
- default-src 'none'; base-uri 'self'; connect-src 'self'; form-action 'self';
img-src 'self' data:; script-src 'self'; style-src 'unsafe-inline'
content-type:
- text/plain; charset=utf-8
date:
- Tue, 15 Oct 2024 04:01:14 GMT
referrer-policy:
- origin-when-cross-origin, strict-origin-when-cross-origin
server:
- GitHub.com
set-cookie:
- _gh_sess=05a6i77a0k6QZ7mJnH%2BnWIliR5guipRh0Z%2Fs73RhXbNuLqVAnKu19dDhM1kWOhpwMFe8ZSuBFfzUJOop9ta9yqM6ZL3qs0chytbmyaEh%2F6YELXvhhcXHO1za3tMCbJBynfJ2HGeIRPC1GyepCLgKnyg13K1gRKMbFbxNTUgqERu59BrD%2FNGDDp1bdz4EYNrl5THCBqSX8Ozp%2Foi1ZKPOaJK0LujquBpWJqd7CQ09E9EUxeIqUSeKPPrUv4S41%2B8B9pLJDrHign95vSXBE48xMQ%3D%3D--N%2F4dD85JrQ2c5oY5--X7gxxV%2Bs35GOWsptYdJVPw%3D%3D;
Path=/; HttpOnly; Secure; SameSite=Lax
- _octo=GH1.1.98402674.1728964874; Path=/; Domain=github.com; Expires=Wed, 15
Oct 2025 04:01:14 GMT; Secure; SameSite=Lax
- logged_in=no; Path=/; Domain=github.com; Expires=Wed, 15 Oct 2025 04:01:14
GMT; HttpOnly; Secure; SameSite=Lax
strict-transport-security:
- max-age=31536000; includeSubdomains; preload
vary:
- X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Encoding, Accept,
X-Requested-With
x-content-type-options:
- nosniff
x-frame-options:
- deny
x-github-request-id:
- 6596:211F6C:2906DAC:2D82A98:670DE90A
x-xss-protection:
- '0'
status:
code: 404
message: Not Found
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
CommandName:
- apic api show
Connection:
- keep-alive
ParameterSetName:
- -g -n --api-id
User-Agent:
- AZURECLI/2.63.0 azsdk-python-core/1.28.0 Python/3.11.9 (Windows-10-10.0.22631-SP0)
method: GET
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clirg000001/providers/Microsoft.ApiCenter/services/clitest000002/workspaces/default/apis/swaggerpetstore?api-version=2024-03-01
response:
body:
string: '{"code":"404"}'
headers:
api-supported-versions:
- 2023-07-01-preview, 2024-03-01, 2024-03-15-preview
cache-control:
- no-cache
content-length:
- '14'
content-type:
- application/json; charset=utf-8
date:
- Tue, 15 Oct 2024 04:01:15 GMT
expires:
- '-1'
pragma:
- no-cache
strict-transport-security:
- max-age=31536000; includeSubDomains
vary:
- Accept-Encoding
x-cache:
- CONFIG_NOCACHE
x-content-type-options:
- nosniff
x-ms-ratelimit-remaining-subscription-global-reads:
- '16499'
x-msedge-ref:
- 'Ref A: F3CFA1D4358D4160A2BCF0E69AEE0789 Ref B: MAA201060515025 Ref C: 2024-10-15T04:01:14Z'
x-powered-by:
- ASP.NET
status:
code: 404
message: Not Found
version: 1
Loading