Skip to content

Keep OpenAPI application-agnostic and move credential policy to consumers - #48

Merged
glenn-jocher merged 2 commits into
mainfrom
fix/consumer-auth-provider
Sep 7, 2026
Merged

Keep OpenAPI application-agnostic and move credential policy to consumers#48
glenn-jocher merged 2 commits into
mainfrom
fix/consumer-auth-provider

Conversation

@glenn-jocher

@glenn-jocher glenn-jocher commented Sep 7, 2026

Copy link
Copy Markdown
Member

The saved-settings resolver introduced in #47 embeds one consumer's credential discovery policy in a general OpenAPI-to-SDK converter. Delete that policy from the generator and replace it with optional python.authProvider: a consumer-owned Python module exporting get_api_key() -> str | None, copied into the generated package. Default clients continue to resolve explicit and environment credentials; an opted-in provider supplies the final fallback.

ultralytics/sdk owns its own provider, including every Ultralytics settings path and fallback rule. Any independent API provider can supply different credential discovery without changing this converter. The hook is language-scoped and does not inspect or modify the API contract.

Add a critical product-boundary section to AGENTS.md: OpenAPI is a standalone general-purpose SDK/docs product competing with Stainless and Scalar, must remain usable by third parties, and must never inherit ML-package or Platform-specific behavior. Product naming configuration is explicitly insufficient to justify application-specific policy.

The generator change deletes more code than it adds and reuses the existing consumer-source inclusion pattern used for package READMEs. No plugin framework or application dependency is introduced.

Validation: 19 existing generator tests including configured source inclusion, typecheck, lint, unused-code check, and regeneration of all 86 Platform operations with the SDK-owned provider. SDK integration changes remain on ultralytics/sdk#56.

🛠️ PR Summary

Made with ❤️ by Ultralytics Actions

🌟 Summary

The OpenAPI generator now delegates optional Python credential discovery to a consumer-provided provider instead of embedding saved-settings policy, keeping the converter application-agnostic.

📊 Key Changes

  • Replaced apiKey.settings with optional python.authProvider, which points to a consumer-owned Python module exporting get_api_key().
  • Copies the provider into the generated package as _auth.py and uses it as the final credential fallback after explicit credentials and the configured environment variable.
  • Removed platform-specific saved-settings resolution, including filesystem paths, fallback directories, and settings-file parsing, from generated clients.
  • Added an explicit product-boundary policy to AGENTS.md requiring application-specific SDK behavior to remain in consumer repositories such as ultralytics/sdk.
  • Updated generator coverage for provider inclusion, missing-provider failures, and generated client integration.

🎯 Purpose & Impact

  • Generated synchronous and asynchronous Python clients remain independent by default; without python.authProvider, credentials resolve from the explicit argument or environment variable only.
  • With a provider configured, its get_api_key() result is used once during client initialization as the final fallback, while an explicit empty string still disables authentication.
  • Consumers can implement their own credential storage and discovery rules without modifying the OpenAPI converter or API contract.

@UltralyticsAssistant UltralyticsAssistant added documentation Improvements or additions to documentation enhancement New feature or request labels Sep 7, 2026
@UltralyticsAssistant

Copy link
Copy Markdown
Member

👋 Hello @glenn-jocher, thank you for submitting a ultralytics/openapi 🚀 PR! This automated message confirms your contribution was received, and an Ultralytics engineer will assist with the review. To ensure a seamless integration of your work, please review the following checklist:

  • Define a Purpose: Clearly explain the purpose of your fix or feature in your PR description, and link to any relevant issues. Ensure your commit messages are clear, concise, and adhere to the project's conventions.
  • Synchronize with Source: Confirm your PR is synchronized with the ultralytics/openapi main branch. If it's behind, update it by clicking the 'Update branch' button or by running git pull and git merge main locally.
  • Ensure CI Checks Pass: Verify all Ultralytics Continuous Integration (CI) checks are passing. If any checks fail, please address the issues.
  • Update Documentation: Update the relevant documentation for any new or modified features.
  • Add Tests: If applicable, include or update tests to cover your changes, and confirm that all tests are passing.
  • Sign the CLA: Please ensure you have signed our Contributor License Agreement if this is your first Ultralytics PR by writing "I have read the CLA Document and I sign the CLA" in a new message.
  • Minimize Changes: Limit your changes to the minimum necessary for your bug fix or feature addition. "It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is." — Bruce Lee

For more guidance, please refer to our Contributing Guide. Don't hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀

@UltralyticsAssistant UltralyticsAssistant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 PR Review

Made with ❤️ by Ultralytics Actions

Reviewed the configuration, Python generator, tests, README, and product-boundary guidance. The provider fallback and package inclusion are otherwise consistent with the requested design, but invalid provider paths can now delete existing generated output before generation fails.

💬 Posted 1 inline comment
  • 💡 MEDIUM lib/generators/python.ts:865 The provider file is read lazily inside Bun.write, but output has already been recursively deleted at line 857. If authProvider is missing, unreadable, or otherwise invalid, generation rejects only after removing the previous generated package and may leave a partial output. Read and validate the provider source before rm(output, ...), then write the already-read contents.

@UltralyticsAssistant UltralyticsAssistant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 PR Review 2

Made with ❤️ by Ultralytics Actions

Review 2: the previous output-deletion issue is addressed by reading the configured provider before removing the output directory. The auth-provider hook, path resolution, and generated credential fallback are consistent with the requested design, with no new concrete regressions found. LGTM.

@glenn-jocher
glenn-jocher merged commit 2458d13 into main Sep 7, 2026
5 checks passed
@glenn-jocher
glenn-jocher deleted the fix/consumer-auth-provider branch September 7, 2026 16:43
@UltralyticsAssistant

Copy link
Copy Markdown
Member

🎉 PR #48 has been merged—thank you, @glenn-jocher!

“Simplicity is the ultimate sophistication.” — Leonardo da Vinci

This change keeps generated Python clients application-agnostic by delegating optional credential discovery to consumer-provided providers, while preserving explicit credentials and environment-variable fallback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants