Skip to content

Commit 33c5dc1

Browse files
authored
Add create command to create a registered API (#18)
1 parent 0e2e3c0 commit 33c5dc1

File tree

6 files changed

+634
-0
lines changed

6 files changed

+634
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
Added
3+
-----
4+
5+
* Add ``create`` CLI command to create a registered API from an OpenAPI spec.

src/globus_registered_api/cli.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,80 @@ def update_registered_api(
350350
click.echo(f"Edited: {res['edited_timestamp']}")
351351

352352

353+
@cli.command("create")
354+
@click.argument("openapi_spec")
355+
@click.argument("method", type=click.Choice(HTTP_METHODS, case_sensitive=False))
356+
@click.argument("route")
357+
@click.argument("name")
358+
@click.option(
359+
"--content-type",
360+
default="*",
361+
help="Target content-type for request body (required if multiple exist)",
362+
)
363+
@click.option(
364+
"--description",
365+
required=True,
366+
help="Description for the registered API",
367+
)
368+
@click.option("--format", type=click.Choice(["json", "text"]), default="text")
369+
@click.pass_context
370+
def create_registered_api(
371+
ctx: click.Context,
372+
openapi_spec: str,
373+
method: str,
374+
route: str,
375+
name: str,
376+
content_type: str,
377+
description: str,
378+
format: str,
379+
) -> None:
380+
"""
381+
Create a new registered API from an OpenAPI specification.
382+
383+
Extracts a target endpoint from an OpenAPI spec and registers it with
384+
the Flows service.
385+
386+
OPENAPI_SPEC - A filepath or URL to an OpenAPI specification (JSON or YAML).
387+
388+
METHOD - Target API's HTTP method (e.g., get, post, put, delete).
389+
390+
ROUTE - Target API's route path (e.g., /items or /items/{item_id}).
391+
392+
NAME - Name for the registered API.
393+
394+
Example:
395+
396+
globus-registered-api create ./spec.json get /items "My API"
397+
--description "My API"
398+
"""
399+
try:
400+
target = TargetSpecifier.create(method, route, content_type)
401+
except ValueError as e:
402+
raise click.ClickException(str(e))
403+
404+
try:
405+
result = process_target(openapi_spec, target)
406+
except (OpenAPILoadError, TargetNotFoundError, AmbiguousContentTypeError) as e:
407+
raise click.ClickException(str(e))
408+
409+
app: UserApp | ClientApp = ctx.obj
410+
flows_client = _create_flows_client(app)
411+
412+
res = flows_client.create_registered_api(
413+
name=name,
414+
description=description,
415+
target=result.to_dict(),
416+
)
417+
418+
if format == "json":
419+
click.echo(json.dumps(res.data, indent=2))
420+
else:
421+
click.echo(f"ID: {res['id']}")
422+
click.echo(f"Name: {res['name']}")
423+
click.echo(f"Description: {res['description']}")
424+
click.echo(f"Created: {res['created_timestamp']}")
425+
426+
353427
# --- willdelete command group ---
354428

355429

src/globus_registered_api/extended_flows_client.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,25 @@ def update_registered_api(
122122
body["roles"] = roles
123123

124124
return self.patch(f"/registered_apis/{registered_api_id}", data=body)
125+
126+
def create_registered_api(
127+
self,
128+
name: str,
129+
description: str,
130+
target: dict[str, t.Any],
131+
) -> GlobusHTTPResponse:
132+
"""
133+
Create a new registered API.
134+
135+
:param name: Name for the registered API
136+
:param description: Description for the registered API
137+
:param target: Target definition dict (from OpenAPITarget.to_dict())
138+
:return: Response containing the created registered API
139+
"""
140+
body: dict[str, t.Any] = {
141+
"name": name,
142+
"description": description,
143+
"target": target,
144+
}
145+
146+
return self.post("/registered_apis", data=body)

tests/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
UPDATE_REGISTERED_API_URL = re.compile(
2020
r"https://.*flows.*\.globus\.org/registered_apis/[a-f0-9-]+"
2121
)
22+
CREATE_REGISTERED_API_URL = re.compile(
23+
r"https://.*flows.*\.globus\.org/registered_apis$"
24+
)
2225

2326

2427
@pytest.fixture(autouse=True)

0 commit comments

Comments
 (0)