# API ## Endpoint reference API return type classes are mostly defined in api/api.ts
endpoint method description parameters minimal authorization response
/status GET get online user count and active game count none none ```ts { users: int, games: int, version: { commit: string, number: string } } ```
/auth/login POST log in with email or username ```ts { email: string, password: string } ``` none empty response with the set_cookie header
/auth/signup POST sign up ```ts { username: string, email: string, password: string } ``` none empty response with the set_cookie header
/user/info POST get user info by id ```ts { id: userID; } ``` none ```ts { userInfo; } ```
/user/info GET none user ```ts { userInfo; } ```
/user/games POST get games of user ```ts { id: userID; } ``` none ```ts { games: Array, totals: userGameTotals } ```
/user/games GET none user ```ts { games: Array, totals: userGameTotals } ```
/user/avatar?id= GET fetch avatar as .png using url parameter none none PNG image
/user/avatar GET fetch avatar as .png none user PNG image
/user/avatar POST update avatar note: avatar is a client-resized 256x256 .png base64-encoded image, request returns error when image is not .png or larger than 256x256 ```ts { image: base64PNG; } ``` user none
/user/prefrences GET fetch user preferences none user ```ts { preferences: userPreferences; } ```
/user/prefrences POST change user preferences ```ts { newPreferences: userPreferences; } ``` user none
/user/password POST update password ```ts { password: string, newPassword: string, } ``` user none
/user/email POST update email ```ts { password: string, email: string, } ``` user none
/user/username POST update username ```ts { password: string, username: string, } ``` user none
/user/status POST update status ```ts { status: string; } ``` user none
/social/request POST send a friend request to a user by user id ```ts { id: userID; } ``` user none
/social/accept POST accept a friend request ```ts { id: userID; } ``` user none
/social/remove POST remove a friend from your friend list or delete a friend request from a user ```ts { id: userID; } ``` user none
/social/search POST search for users by username or status ```ts { query: string; } ``` none ```ts { results: Array } ```
/social/block POST block a user ```ts { id: userID; } ``` user none
/social/unblock POST unblock a user ```ts { id: userID; } ``` user none
/social/list/requests GET get a list of unaccepted friend requests none user ```ts { requests: Array } ```
/social/list/blocks GET get a list of blocked people none user ```ts { blocks: Array } ```
/social/list/friends GET get a list of your friends none user ```ts { friends: Array } ```
/game/new POST create a new private game none user ```ts { id: gameID, player_1: boolean, game_started: boolean, } ```
/game/random POST join or create a public game none user ```ts { id: gameID, player_1: boolean, game_started: boolean, } ```
/game/info POST get game info by game id ```ts { id: gameID; } ``` user ```ts { gameInfo; } ```
/game/accept POST accept game invite or rematch ```ts { id: gameID; } ``` user ```ts { id: gameID, player_1: boolean, game_started: boolean, } ```
/game/spectate POST spectate a game by id ```ts { id: gameID; } ``` none ```ts { id: gameID, player_1: boolean, game_started: boolean, } ```
/verify/discord GET get a one-time code for verifying account ownership with the discord bot none user ```ts { code: string; } ```
## Events These are events that are fired by the socket.io connection
event description data direction context
fieldUpdate recieve new playfield from server { field: string } s -> c game
turnUpdate recieve if it's player 1's move { player1: boolean } s -> c game
gameStart sent when game starts none s -> c game
finish sent when game finishes none s -> c game
resign send to resign, is then forwarded to all subscribed clients none s <-> c game
newMove send a new move { move: int, game_id: string } s <- c game
registerGameListener listen to events for a game { id: string } s <- c game
incomingFriendRequest get notified of friend request none s -> c global
changedRelation get notified of a different relation to someone { id: string } s -> c global
## How to test API endpoints ```sh # If you're running the standalone flask server: curl http://localhost:5000/ # If you're running flask and nginx at the same time: curl http://localhost:2080/api/ ``` ## Example endpoint Here's a simple endpoint that returns a "hello world" JSON object: ```py # api/tests/example.py from flask import Blueprint example = Blueprint('example', __name__) @example.route('/example') def index(): # python dictionaries are automatically converted to JSON by flask return {"hello": "world"}, 200 # flask returns http code 200 by default if no code is explicitly defined # define a `dynamic_route` variable at the end of your endpoint definition file # dynamic_route[0] is the namespace # dynamic_route[1] is your flask.Blueprint dynamic_route = ["/tests", status] # this endpoint will be routed to /tests/example # \___/ \_____/ # | | # | endpoint (defined by the @Blueprint.route() decorator) # | # namespace (defined in dynamic_route variable) ``` ## Handy utility functions and where to find them All of the paths are defined relative to this (api/) directory. Most of these functions/decorators should also have docstrings for editor autocompletion help, but not all of them do. | utility | description | file | | ---------------------------------- | ------------------------------------------------------------------------ | ------------ | | `@util_two_id(type)` | exposes (token_id, explicit_id) to the endpoint | hierarchy.py | | `@two_person` | exposes (user_1_id, user_2_id) to the endpoint | hierarchy.py | | `@one_person` | exposes (user_id) to the endpoint | hierarchy.py | | `@game_id_with_viewer` | exposes (game_id, viewer?) to the endpoint | hierarchy.py | | `@auth_required(level)` | checks if user is authorized and expose (user_id) to the endpoint | hierarchy.py | | `@io_auth_required(level)` | same as @auth_required but for socket.io event listeners | hierarchy.py | | `all_def([ ... ])` | checks if all items of the list are truthy | util.py | | `all_notdef([ ... ])` | checks if all items of the list are falsy | util.py | | `format_user(user_id, viewer_id?)` | format a user to /api/user/info format with optional viewer for relation | user/info.py | | `format_game(game_id, viewer_id?)` | format a game to /api/game/info format with optional viewer for opponent | game/info.py |