Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create user script to format API sandbox calls for m3api #12

Closed
lucaswerkmeister opened this issue Nov 30, 2021 · 5 comments
Closed

Create user script to format API sandbox calls for m3api #12

lucaswerkmeister opened this issue Nov 30, 2021 · 5 comments
Labels
enhancement New feature or request

Comments

@lucaswerkmeister
Copy link
Owner

The API sandbox can show the request parameters in different formats; two (URL query string and JSON) are built-in, but this list is also extensible via the apisandbox.formatRequest JS hook. It would be nice to create a user script, which people can add to their global.js, which generates a snippet of m3api code to make the request.

Here’s a very quickly sketched version:

mw.hook( 'apisandbox.formatRequest' ).add( function ( items, displayParams, rawParams ) {
  items.push( new OO.ui.MenuOptionWidget( {
    label:'m3api',
    data: new mw.widgets.CopyTextLayout( {
      label: 'm3api call',
      copyText: `session.request( ${JSON.stringify( displayParams, null, '\t' )} );`,
      multiline: true,
      textInput: {
        classes: [ 'mw-apisandbox-textInputCode' ],
        autosize: true,
        maxRows: 6,
      },
    } ),
  } ) );
} );
@lucaswerkmeister lucaswerkmeister added the enhancement New feature or request label Nov 30, 2021
@lucaswerkmeister
Copy link
Owner Author

lucaswerkmeister commented Nov 30, 2021

I think this is where we can be much more opinionated than in the main library, by the way. We’ll almost certainly need to do some guessing anyways (the params we get have already had lists turned into appropriately|separated|strings, for instance, which we should to turn back into arrays or sets), and the code should be seen as a starting point for the developer, so we can afford the risk of not always generating fully correct code, if the benefit is that the code is more useful most of the time.

Specifically, I think we should generate code along these lines:

const session = new Session( 'en.wikipedia.org', {
	formatversion: 2,
	// (suggestion) errorformat: 'plaintext',
}, {
	userAgent: 'm3api-ApiSandbox-helper', // change this :)
	warn: console.warn,
} );
const response = await session.request( {
	action: 'query',
	meta: 'siteinfo',
	siprop: set( 'general', 'statistics' ),
} );

We can hard-code a set of params that “usually” go into the constructor as default params for all requests (formatversion, uselang, errorformat, errorlang, …), and also suggest some of them even when they’re not in the actual parameters (errorformat above; I’d probably do this for formatversion and errorformat). This also means that, if the user already has a session constructor call with similar default params, the session.request() call we generate will be more useful to them, since we’re keeping those params out of that call.

Figuring out which params should be arrays or sets will be tricky. The paraminfo API can help us a bit here, by at least telling us which of the params are multi-valued at all, but distinguishing between sets (mergeable) and arrays (don’t merge) will still be tricky. Maybe we’ll just hard-code a list of params appropriate for one type, and default to the other type for everything else, though I’m not even sure what that would be. (Also, the hook handler has to be synchronous, and we don’t have access to the API sandbox code’s copy of the paraminfo, so we’ll probably just have to request it upfront at initialization time.)

If we have the paraminfo, we can also figure out which request should use { method: 'POST' } as the request options. (But that also leads towards #6, which still needs to be done.)

@lucaswerkmeister
Copy link
Owner Author

Big thanks to @anomiex for anticipating the usefulness of making the request formats extensible and introducing this hook, by the way ❤️

@lucaswerkmeister
Copy link
Owner Author

(Also, the hook handler has to be synchronous, and we don’t have access to the API sandbox code’s copy of the paraminfo, so we’ll probably just have to request it upfront at initialization time.)

Hm, come to think of it… does it have to be synchronous? We have to add some item to the array synchronously, but I don’t think there’s anything stopping us from modifying that item later, asynchronously. The hook gets run as soon as the params have been validated, before the API request itself is even sent, but the user will only see the result once they manually select our custom output format. So we should produce some decent code synchronously, but I don’t think there’s anything stopping us from asynchronously improving it further.

@lucaswerkmeister
Copy link
Owner Author

Some work in progress at https://meta.wikimedia.org/wiki/User:Lucas_Werkmeister/m3api-ApiSandbox-helper.js.

Also, as a user script, this code (unlike the rest of the repository contents) has to be non-modern, and it’s surprisingly annoying :D (especially having to use var instead of const)

@lucaswerkmeister
Copy link
Owner Author

documented and announced, now needs to be added to the README :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant