dc4client package
Submodules
dc4client.dc_client module
- exception dc4client.dc_client.AuthenticationError(message: str, status: int | None = None, detail: str | None = None)[source]
Bases:
ExceptionRaised when authentication fails and the client should stop immediately.
- class dc4client.dc_client.DCClient(match_id: UUID, username: str, password: str, log_level: int = 20, match_team_name: MatchNameModel = MatchNameModel.team1, socket_read_timeout: int | None = 15, enable_tcp_keepalive: bool = True, auto_save_log: bool = True, log_dir: str = 'logs')[source]
Bases:
objectInitialize the DCClient. :param match_id: To identify the match. :type match_id: UUID :param username: Username for authentication. :type username: str :param password: Password for authentication. :type password: str :param log_level: Logging level. :type log_level: int :param match_team_name: The name of the team in the match. :type match_team_name: MatchNameModel :param socket_read_timeout: Timeout in seconds for socket read. Defaults to 15. Set None to disable. :type socket_read_timeout: int | None :param enable_tcp_keepalive: Whether to enable TCP Keep-Alive. Defaults to True. :type enable_tcp_keepalive: bool :param auto_save_log: Whether to enable log buffering and saving. Defaults to True. :type auto_save_log: bool :param log_dir: Directory to save logs. Defaults to “logs”. :type log_dir: str
- get_last_move() ShotInfoSchema | None[source]
Get the last move information from the state data.
- get_stone_coordinates() tuple[list[tuple[float, float]], list[tuple[float, float]]][source]
Get the stone coordinates for both teams from the state data. :returns: A tuple containing two lists of tuples.
The first list contains the coordinates of team0’s stones, and the second list contains the coordinates of team1’s stones.
- Return type:
Tuple[List[Tuple[float, float]], List[Tuple[float, float]]]
- async receive_state_data() AsyncGenerator[StateSchema, None][source]
- Robust SSE receiver with:
explicit reconnect loop (exponential backoff + jitter)
Authorization header (Basic) for wider compatibility
TCP connector with keepalive options
clear logging for connect / disconnect / parse errors
- async send_positioned_stones_info(positioned_stones: PositionedStonesModel) None[source]
This method is to support mixed doubles positioned stones info. Send positioned stones information to the server. :param positioned_stones: Positioned stones information model. :type positioned_stones: PositionedStonesModel
- async send_shot_info(translational_velocity: float, shot_angle: float, angular_velocity=1.5707963267948966)[source]
Send shot information to the server. :param translational_velocity: The translational velocity of the stone. :type translational_velocity: float :param shot_angle: The shot angle of the stone in radians. :type shot_angle: float :param angular_velocity: The angular velocity of the stone. :type angular_velocity: float
- async send_shot_info_dc3(vx: float, vy: float, rotation: str)[source]
Send shot information to the server for DC3 style input. :param vx: The x-component of the velocity of the stone. :type vx: float :param vy: The y-component of the velocity of the stone. :type vy: float :param rotation: The rotation direction of the stone (“cw” for clockwise, “ccw” for counter-clockwise). :type rotation: str
- async send_team_info(team_info: TeamModel) MatchNameModel[source]
Send team information to the server. :param team_info: Team information model. :type team_info: TeamModel
- Returns:
The assigned team name in the match.
- Return type:
- class dc4client.dc_client.JsonLineFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)[source]
Bases:
FormatterFormat log records as single-line JSON. Output keys match:
{“timestamp”: “…”, “logger”: “…”, “level”: “…”, “message”: “…”}
- format(record: LogRecord) str[source]
Format the specified record as text.
The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.
dc4client.match_maker_client module
- class dc4client.match_maker_client.MatchMakerClient(host: str, port: int, username: str, password: str)[source]
Bases:
objectInitialize the MatchMakerClient. :param host: Server host address. :type host: str :param port: Server port number. :type port: int :param username: Username for authentication. :type username: str :param password: Password for authentication. :type password: str
- async create_match(data: ClientDataModel) Any[source]
Create a match on the server.
- Returns:
Parsed JSON returned by the server (typically a match_id).
- Raises:
RuntimeError – When the request fails (includes status/body).
dc4client.receive_data module
- class dc4client.receive_data.CoordinateDataSchema(*, x: float, y: float)[source]
Bases:
BaseModel- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- x: float
- y: float
- class dc4client.receive_data.MatchDataSchema(*, match_id: UUID, first_team_id: UUID, second_team_id: UUID, score_id: UUID, time_limit: int, extra_end_time_limit: int, standard_end_count: int, physical_simulator_id: UUID, tournament_id: UUID, match_name: str, created_at: datetime, started_at: datetime, score: ScoreSchema | None = None, tournament: TournamentSchema | None = None, simulator: PhysicalSimulatorSchema | None = None)[source]
Bases:
BaseModel- created_at: datetime
- extra_end_time_limit: int
- first_team_id: UUID
- match_id: UUID
- match_name: str
- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- physical_simulator_id: UUID
- score: ScoreSchema | None
- score_id: UUID
- second_team_id: UUID
- simulator: PhysicalSimulatorSchema | None
- standard_end_count: int
- started_at: datetime
- time_limit: int
- tournament: TournamentSchema | None
- tournament_id: UUID
- class dc4client.receive_data.MixedDoublesSettingsSchema(*, end_setup_team: str, positioned_stones_pattern: int, power_play_end: PowerPlayEndSchema)[source]
Bases:
BaseModel- end_setup_team: str
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- positioned_stones_pattern: int
- power_play_end: PowerPlayEndSchema
- class dc4client.receive_data.PhysicalSimulatorSchema(*, physical_simulator_id: UUID, simulator_name: str)[source]
Bases:
BaseModel- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- physical_simulator_id: UUID
- simulator_name: str
- class dc4client.receive_data.PlayerSchema(*, player_id: UUID, max_velocity: float, shot_dispersion_rate: float, player_name: str)[source]
Bases:
BaseModel- max_velocity: float
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- player_id: UUID
- player_name: str
- shot_dispersion_rate: float
- class dc4client.receive_data.PowerPlayEndSchema(*, team0: int | None = None, team1: int | None = None)[source]
Bases:
BaseModel- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- team0: int | None
- team1: int | None
- class dc4client.receive_data.ScoreSchema(*, team0: list, team1: list)[source]
Bases:
BaseModel- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- team0: list
- team1: list
- class dc4client.receive_data.ShotInfoSchema(*, translational_velocity: float, angular_velocity: float, shot_angle: float)[source]
Bases:
BaseModel- angular_velocity: float
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- shot_angle: float
- translational_velocity: float
- class dc4client.receive_data.StateSchema(*, winner_team: str | None, end_number: int, team_shot_number: int | None, total_shot_number: int | None, next_shot_team: str | None, first_team_remaining_time: float, second_team_remaining_time: float, first_team_extra_end_remaining_time: float, second_team_extra_end_remaining_time: float, mixed_doubles_settings: MixedDoublesSettingsSchema | None = None, last_move: ShotInfoSchema | None, stone_coordinate: StoneCoordinateSchema | None = None, score: ScoreSchema | None = None)[source]
Bases:
BaseModel- end_number: int
- first_team_extra_end_remaining_time: float
- first_team_remaining_time: float
- last_move: ShotInfoSchema | None
- mixed_doubles_settings: MixedDoublesSettingsSchema | None
- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- next_shot_team: str | None
- score: ScoreSchema | None
- second_team_extra_end_remaining_time: float
- second_team_remaining_time: float
- stone_coordinate: StoneCoordinateSchema | None
- team_shot_number: int | None
- total_shot_number: int | None
- winner_team: str | None
- class dc4client.receive_data.StoneCoordinateSchema(*, data: Dict[str, List[CoordinateDataSchema]])[source]
Bases:
BaseModel- data: Dict[str, List[CoordinateDataSchema]]
- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class dc4client.receive_data.TournamentSchema(*, tournament_id: UUID, tournament_name: str)[source]
Bases:
BaseModel- model_config = {'from_attributes': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- tournament_id: UUID
- tournament_name: str
dc4client.send_data module
- class dc4client.send_data.ClientDataModel(*, game_mode: GameMode = GameMode.standard, tournament: TournamentModel, simulator: PhysicalSimulatorModel, applied_rule: str, time_limit: float, extra_end_time_limit: float, standard_end_count: int, match_name: str, positioned_stones_pattern: int | None = None)[source]
Bases:
BaseModel- applied_rule: str
- extra_end_time_limit: float
- match_name: str
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- positioned_stones_pattern: int | None
- simulator: PhysicalSimulatorModel
- standard_end_count: int
- time_limit: float
- tournament: TournamentModel
- class dc4client.send_data.GameMode(*values)[source]
Bases:
str,Enum- mixed_doubles = 'mixed_doubles'
- standard = 'standard'
- class dc4client.send_data.MatchModel(*, time_limit: int, extra_end_time_limit: int, standard_end_count: int, match_name: str)[source]
Bases:
BaseModelTo get match_id from server
- extra_end_time_limit: int
- match_name: str
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- standard_end_count: int
- time_limit: int
- class dc4client.send_data.MatchNameModel(*values)[source]
Bases:
str,Enum- team0 = 'team0'
- team1 = 'team1'
- class dc4client.send_data.MixedDoublesTeamModel(*, use_default_config: bool, team_name: str, match_team_name: MatchNameModel = MatchNameModel.team1, player1: PlayerModel, player2: PlayerModel)[source]
Bases:
BaseModelTeam configuration for Mix Doubles.
Note
Current 4-person team config uses player1..player4. Mix Doubles typically uses 2 players, so this model is provided for clients that want to represent that explicitly.
- match_team_name: MatchNameModel
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- player1: PlayerModel
- player2: PlayerModel
- team_name: str
- use_default_config: bool
- class dc4client.send_data.PhysicalSimulatorModel(*, simulator_name: str)[source]
Bases:
BaseModel- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- simulator_name: str
- class dc4client.send_data.PlayerModel(*, max_velocity: float, shot_std_dev: float, angle_std_dev: float, player_name: str)[source]
Bases:
BaseModel- angle_std_dev: float
- max_velocity: float
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- player_name: str
- shot_std_dev: float
- class dc4client.send_data.PositionedStonesModel(*values)[source]
Bases:
str,Enum- center_guard = 'center_guard'
- center_house = 'center_house'
- pp_left = 'pp_left'
- pp_right = 'pp_right'
- class dc4client.send_data.ScoreModel(*, first_team_score: List[int], second_team_score: List[int])[source]
Bases:
BaseModel- first_team_score: List[int]
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- second_team_score: List[int]
- class dc4client.send_data.ShotInfoModel(*, translational_velocity: float, angular_velocity: float | None, shot_angle: float)[source]
Bases:
BaseModel- angular_velocity: float | None
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- shot_angle: float
- translational_velocity: float
- class dc4client.send_data.StateModel(*, end_number: int, team_shot_number: int, total_shot_number: int)[source]
Bases:
BaseModel- end_number: int
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- team_shot_number: int
- total_shot_number: int
- class dc4client.send_data.StoneCoordinates(*, stone_data: Json)[source]
Bases:
BaseModel- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- stone_data: Json
- class dc4client.send_data.TeamModel(*, use_default_config: bool, team_name: str, match_team_name: MatchNameModel = MatchNameModel.team1, player1: PlayerModel, player2: PlayerModel, player3: PlayerModel | None = None, player4: PlayerModel | None = None)[source]
Bases:
BaseModel- match_team_name: MatchNameModel
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- player1: PlayerModel
- player2: PlayerModel
- player3: PlayerModel | None
- player4: PlayerModel | None
- team_name: str
- use_default_config: bool