sig
  type query = (string * string option) list
  type language = string
  type user = string
  type token_type = [ `EDIT | `MOVE ]
  type search_type = [ `TEXT | `TITLE ]
  type rc_type = [ `EDIT | `LOG | `NEW ]
  type redirect_filter = [ `ALL | `NOT_REDIRECT | `REDIRECT ]
  type user_filter =
      [ `ALL | `EXCLUDE of Datatypes.user | `ONLY of Datatypes.user ]
  type category_filter = [ `HIDDEN | `NOT_HIDDEN ]
  type minor_flag = [ `DEFAULT | `MINOR | `NOT_MINOR ]
  type watch_flag = [ `DEFAULT | `NO_CHANGE | `UNWATCH | `WATCH ]
  type create_flag = [ `CREATE_ONLY | `DEFAULT | `NO_CREATE | `RECREATE ]
  type edit_status = [ `NEW | `NO_CHANGE | `UPDATE ]
  type move_status = [ `NO_REDIRECT | `REDIRECTED ]
  type upload_status = [ `SUCCESS | `WARNING ]
  type 'a relative_id =
      [ `CURRENT | `ID of 'WTypes.Id.t | `NEXT | `PREVIOUS ]
  type order = [ `DECR | `INCR ]
  type token = {
    token : string;
    token_type : Datatypes.token_type;
    token_ts : WTypes.Timestamp.t;
  }
  type page = {
    page_title : WTypes.Title.t;
    page_id : WTypes.page_t WTypes.Id.t;
    page_touched : WTypes.Timestamp.t;
    page_lastrevid : WTypes.revision_t WTypes.Id.t;
    page_length : int;
    page_redirect : bool;
    page_new : bool;
  }
  type revision = {
    rev_id : WTypes.revision_t WTypes.Id.t;
    rev_page : WTypes.page_t WTypes.Id.t;
    rev_timestamp : WTypes.Timestamp.t;
    rev_user : string;
    rev_comment : string;
    rev_minor : bool;
  }
  type diff = {
    diff_src : WTypes.revision_t WTypes.Id.t;
    diff_dst : WTypes.revision_t WTypes.Id.t;
    diff_val : string;
  }
  type langlink = {
    lang_title : string;
    lang_language : Datatypes.language;
  }
  type namespace_info = {
    ns_id : WTypes.namespace;
    ns_name : string;
    ns_canonical : string option;
    ns_content : bool;
    ns_case_sensitive : bool;
    ns_subpages : bool;
    ns_aliases : string list;
  }
  type user_info = {
    user_id : WTypes.user_t WTypes.Id.t;
    user_name : string;
    user_anon : bool;
    user_groups : string list;
    user_rights : string list;
    user_editcount : int;
  }
  type category_info = {
    cat_name : string;
    cat_size : int;
    cat_pages : int;
    cat_files : int;
    cat_subcats : int;
    cat_hidden : bool;
  }
  type rc_info = {
    rc_id : WTypes.rc_t WTypes.Id.t;
    rc_type : Datatypes.rc_type;
    rc_title : WTypes.Title.t;
    rc_user : Datatypes.user;
    rc_comment : string;
    rc_minor : bool;
    rc_anon : bool;
    rc_oldrevid : WTypes.revision_t WTypes.Id.t;
    rc_newrevid : WTypes.revision_t WTypes.Id.t;
    rc_timestamp : WTypes.Timestamp.t;
    rc_logtype : string option;
    rc_logaction : string option;
  }
  type site_statistics = {
    stats_pages : int;
    stats_articles : int;
    stats_edits : int;
    stats_images : int;
    stats_users : int;
    stats_activeusers : int;
    stats_admins : int;
    stats_jobs : int;
  }
  type interwiki_info = {
    iw_prefix : string;
    iw_url : string;
    iw_local : bool;
  }
  type move_result = {
    moved_status : Datatypes.move_status;
    moved_page : string * string;
    moved_talk : (string * string) option;
    moved_subpage : (string * string) list;
    moved_subtalk : (string * string) list;
  }
  type upload_result = {
    upload_status : Datatypes.upload_status;
    upload_filekey : string option;
  }
  type site = { site_name : string; site_api : string; site_lang : string; }
  class type session =
    object
      method edit_token : Datatypes.token
      method get_call : Datatypes.query -> Call.call
      method is_valid : bool
      method logout : unit -> unit
      method maxlag : int
      method post_call : Datatypes.query -> Call.call
      method save : string
      method set_maxlag : int -> unit
      method site : Datatypes.site
      method upload_call : Datatypes.query -> string -> Call.call
      method userid : WTypes.user_t WTypes.Id.t
      method username : string option
    end
end