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

Feature/SK-1265 | Implement SQL store #785

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
2710e6e
added graphql server
niklastheman Dec 20, 2024
bab877e
sessions added
niklastheman Dec 20, 2024
9c4ad30
get single session
niklastheman Dec 20, 2024
0fe3cfd
added models
niklastheman Dec 20, 2024
a29f0a1
added validations
niklastheman Dec 20, 2024
750cf3a
statuses added
niklastheman Dec 20, 2024
6dcb6af
added plura/singular naming to follow convention
niklastheman Dec 20, 2024
0e596dc
added abstract parent class, Store along with MongoDBStore
niklastheman Dec 23, 2024
9271df6
removed use_typings option
niklastheman Dec 23, 2024
e55ad72
clean up
niklastheman Dec 23, 2024
b069844
merged SK-1109
niklastheman Dec 23, 2024
0ec6d6c
removed use_typings, changes to complie with feature/SK-1109
niklastheman Dec 23, 2024
4ebb1eb
started on replacing mongostatestore
niklastheman Dec 27, 2024
eaf75c0
removed get_combiners from mongostatestore and started using combiner…
niklastheman Dec 27, 2024
08f8583
removed add/delete combiner from network and mongostatestore
niklastheman Dec 28, 2024
fab412a
moved get and list clients from mongostatestore
niklastheman Dec 28, 2024
328217b
update sessions with session_store
niklastheman Dec 30, 2024
5a5303f
removed set_session_status from mongostatestore
niklastheman Dec 30, 2024
1ac6880
added round_store to combiner
niklastheman Dec 30, 2024
9d9bfa8
clean up
niklastheman Dec 30, 2024
010528f
upload model moved to api/v1/models
niklastheman Dec 30, 2024
d0df714
removed get model
niklastheman Dec 30, 2024
70fc83d
moved add client to api/v1/clients/add
niklastheman Dec 30, 2024
d542140
moved download package to api/v1/packages/download
niklastheman Dec 30, 2024
a1ac5b1
moved get checksum to api/v1/packages/checksum
niklastheman Dec 30, 2024
839bf39
removed old client and old package runtime class
niklastheman Dec 30, 2024
db14426
mongostatestore dependecy to control removed and repository dependecy…
niklastheman Dec 30, 2024
57ba8d1
get_client_config moved to api/v1/clients/config
niklastheman Jan 1, 2025
5fdc75c
removed API (interface) class
niklastheman Jan 1, 2025
64fdd83
added indexes to mogno stores
niklastheman Jan 1, 2025
392c4ad
removed mongostatestore completely
niklastheman Jan 1, 2025
d8d28f0
removed old api tests
niklastheman Jan 1, 2025
6824cf8
deprecate old endpoint
niklastheman Jan 1, 2025
c02703b
Added sqlalchemy and used sql for storing package info
niklastheman Jan 2, 2025
c5fdaa9
added where clause to list packages
niklastheman Jan 2, 2025
df1ac2a
package sql store v1
niklastheman Jan 2, 2025
1ddeaa0
added count to package sql store
niklastheman Jan 2, 2025
da59555
fixed some typings
niklastheman Jan 2, 2025
4481245
added sql session store
niklastheman Jan 3, 2025
878fc1b
session sql store v1
niklastheman Jan 3, 2025
f71d10c
added count to session sql store
niklastheman Jan 3, 2025
62b8a4c
started on models sql store
niklastheman Jan 3, 2025
a47616a
sql model store works for training
niklastheman Jan 5, 2025
14fb7d0
added ancestors and descendants to sql models store and thus model st…
niklastheman Jan 6, 2025
9ea7304
added postgres
niklastheman Jan 6, 2025
2df0655
started on rounds sql store
niklastheman Jan 6, 2025
caa1add
added sql round store
niklastheman Jan 8, 2025
6a6b283
added get_latest_round_id to round store
niklastheman Jan 8, 2025
420e12f
added session and model id as foregin keys in round config model
niklastheman Jan 8, 2025
420f347
added status store
niklastheman Jan 8, 2025
099ff2e
added validations sql store
niklastheman Jan 8, 2025
dbf3f5a
added client store
niklastheman Jan 8, 2025
fd1c34b
started on prediction store
niklastheman Jan 8, 2025
633d7cf
prediction store v1
niklastheman Jan 8, 2025
51c463c
create sql tables only if sql stores
niklastheman Jan 8, 2025
6920404
linting fix
niklastheman Jan 8, 2025
34a5818
sqllite postgres or mongo based on env:s. moved table creation to cot…
niklastheman Jan 9, 2025
a7d7e08
implemented connected_client_count for client sql store
niklastheman Jan 9, 2025
361d967
clean up
niklastheman Jan 9, 2025
b8f89b7
client_store update should be like every other update
niklastheman Jan 9, 2025
669c154
run table creation script from combiner to fix timing issue
niklastheman Jan 9, 2025
fdc77d9
merge of master
niklastheman Jan 10, 2025
ab7eafc
removed debug logging
niklastheman Jan 10, 2025
6816327
This SQL query depends on a user-provided value fix.
niklastheman Jan 10, 2025
d734c55
ruff linting fix#
niklastheman Jan 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion config/settings-combiner.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ statestore:
password: password
host: mongo
port: 6534

postgres_config:
username: fedn_admin
password: password
host: fedn_postgres
port: 5432

storage:
storage_type: S3
storage_config:
Expand Down
5 changes: 5 additions & 0 deletions config/settings-reducer.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ statestore:
password: password
host: mongo
port: 6534
postgres_config:
username: fedn_admin
password: password
host: fedn_postgres
port: 5432

storage:
storage_type: S3
Expand Down
10 changes: 10 additions & 0 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ services:
ports:
- 8081:8081

fedn_postgres:
image: postgres:15
environment:
POSTGRES_USER: fedn_admin
POSTGRES_PASSWORD: password
POSTGRES_DB: fedn_db
ports:
- "5432:5432"

api-server:
environment:
- GET_HOSTS_FROM=dns
Expand All @@ -73,6 +82,7 @@ services:
depends_on:
- minio
- mongo
- fedn_postgres
command:
- controller
- start
Expand Down
10 changes: 10 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ services:
- ME_CONFIG_BASICAUTH_PASSWORD=password
ports:
- 8081:8081

fedn_postgres:
image: postgres:15
environment:
POSTGRES_USER: fedn_admin
POSTGRES_PASSWORD: password
POSTGRES_DB: fedn_db
ports:
- "5432:5432"

api-server:
environment:
Expand All @@ -72,6 +81,7 @@ services:
depends_on:
- minio
- mongo
- fedn_postgres
command:
- controller
- start
Expand Down
118 changes: 1 addition & 117 deletions fedn/cli/client_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from fedn.cli.main import main
from fedn.cli.shared import CONTROLLER_DEFAULTS, apply_config, get_api_url, get_token, print_response
from fedn.common.exceptions import InvalidClientConfig
from fedn.network.clients.client import Client
from fedn.network.clients.client_v2 import Client as ClientV2
from fedn.network.clients.client_v2 import ClientOptions

Expand Down Expand Up @@ -60,13 +59,13 @@ def list_clients(ctx, protocol: str, host: str, port: str, token: str = None, n_
if _token:
headers["Authorization"] = _token


try:
response = requests.get(url, headers=headers)
print_response(response, "clients", None)
except requests.exceptions.ConnectionError:
click.echo(f"Error: Could not connect to {url}")


@click.option("-p", "--protocol", required=False, default=CONTROLLER_DEFAULTS["protocol"], help="Communication protocol of controller (api)")
@click.option("-H", "--host", required=False, default=CONTROLLER_DEFAULTS["host"], help="Hostname of controller (api)")
@click.option("-P", "--port", required=False, default=CONTROLLER_DEFAULTS["port"], help="Port of controller (api)")
Expand All @@ -83,7 +82,6 @@ def get_client(ctx, protocol: str, host: str, port: str, token: str = None, id:
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="clients")
headers = {}


_token = get_token(token)

if _token:
Expand All @@ -92,127 +90,13 @@ def get_client(ctx, protocol: str, host: str, port: str, token: str = None, id:
if id:
url = f"{url}{id}"


try:
response = requests.get(url, headers=headers)
print_response(response, "client", id)
except requests.exceptions.ConnectionError:
click.echo(f"Error: Could not connect to {url}")


@client_cmd.command("start-v1")
@click.option("-d", "--discoverhost", required=False, help="Hostname for discovery services(reducer).")
@click.option("-p", "--discoverport", required=False, help="Port for discovery services (reducer).")
@click.option("--token", required=False, help="Set token provided by reducer if enabled")
@click.option("-n", "--name", required=False, default="client" + str(uuid.uuid4())[:8])
@click.option("-i", "--client_id", required=False)
@click.option("--local-package", is_flag=True, help="Enable local compute package")
@click.option("--force-ssl", is_flag=True, help="Force SSL/TLS for REST service")
@click.option("-u", "--dry-run", required=False, default=False)
@click.option("-s", "--secure", required=False, default=False)
@click.option("-pc", "--preshared-cert", required=False, default=False)
@click.option("-v", "--verify", is_flag=True, help="Verify SSL/TLS for REST service")
@click.option("-c", "--preferred-combiner", type=str, required=False, default="", help="name of the preferred combiner")
@click.option("--combiner", type=str, required=False, default="", help="Skip combiner assignment from discover service and attatch directly to combiner host.")
@click.option("--combiner-port", type=str, required=False, default="12080", help="Combiner port, need to be used with --combiner")
@click.option("--proxy-server", type=str, required=False, default="", help="gRPC proxy server, need to be used together with --combiner")
@click.option("-va", "--validator", required=False, default=True)
@click.option("-tr", "--trainer", required=False, default=True)
@click.option("-in", "--init", required=False, default=None, help="Set to a filename to (re)init client from file state.")
@click.option("-l", "--logfile", required=False, default=None, help="Set logfile for client log to file.")
@click.option("--heartbeat-interval", required=False, default=2)
@click.option("--reconnect-after-missed-heartbeat", required=False, default=30)
@click.option("--verbosity", required=False, default="INFO", type=click.Choice(["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"], case_sensitive=False))
@click.pass_context
def client_start_cmd(
ctx,
discoverhost,
discoverport,
token,
name,
client_id,
local_package,
force_ssl,
dry_run,
secure,
preshared_cert,
verify,
preferred_combiner,
combiner,
combiner_port,
proxy_server,
validator,
trainer,
init,
logfile,
heartbeat_interval,
reconnect_after_missed_heartbeat,
verbosity,
):
""":param ctx:
:param discoverhost:
:param discoverport:
:param token:
:param name:
:param client_id:
:param remote:
:param dry_run:
:param secure:
:param preshared_cert:
:param verify_cert:
:param preferred_combiner:
:param init:
:param logfile:
:param hearbeat_interval
:param reconnect_after_missed_heartbeat
:param verbosity
:return:
"""
remote = False if local_package else True
config = {
"discover_host": discoverhost,
"discover_port": discoverport,
"token": token,
"name": name,
"client_id": client_id,
"remote_compute_context": remote,
"force_ssl": force_ssl,
"dry_run": dry_run,
"secure": secure,
"preshared_cert": preshared_cert,
"verify": verify,
"preferred_combiner": preferred_combiner,
"combiner": combiner,
"combiner_port": combiner_port,
"proxy_server": proxy_server,
"validator": validator,
"trainer": trainer,
"logfile": logfile,
"heartbeat_interval": heartbeat_interval,
"reconnect_after_missed_heartbeat": reconnect_after_missed_heartbeat,
"verbosity": verbosity,
}

if init:
apply_config(init, config)
click.echo(f"\nClient configuration loaded from file: {init}")
click.echo("Values set in file override defaults and command line arguments...\n")

# proxy_server needs combiner check
if config["proxy_server"]:
if not config["combiner"]:
click.echo("--proxy-server/proxy_server requires a combiner host in --combiner/combiner")
return
try:
validate_client_config(config)
except InvalidClientConfig as e:
click.echo(f"Error: {e}")
return

client = Client(config)
client.run()


def _validate_client_params(config: dict):
api_url = config["api_url"]
combiner = config["combiner"]
Expand Down
105 changes: 0 additions & 105 deletions fedn/cli/run_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
import click
import yaml

from fedn.cli.client_cmd import validate_client_config
from fedn.cli.main import main
from fedn.cli.shared import apply_config
from fedn.common.exceptions import InvalidClientConfig
from fedn.common.log_config import logger
from fedn.network.clients.client import Client
from fedn.utils.dispatcher import Dispatcher, _read_yaml_file


Expand Down Expand Up @@ -172,108 +169,6 @@ def build_cmd(ctx, path, keep_venv):
delete_virtual_environment(dispatcher)


@run_cmd.command("client")
@click.option("-d", "--discoverhost", required=False, help="Hostname for discovery services(reducer).")
@click.option("-p", "--discoverport", required=False, help="Port for discovery services (reducer).")
@click.option("--token", required=False, help="Set token provided by reducer if enabled")
@click.option("-n", "--name", required=False, default="client" + str(uuid.uuid4())[:8])
@click.option("-i", "--client_id", required=False)
@click.option("--local-package", is_flag=True, help="Enable local compute package")
@click.option("--force-ssl", is_flag=True, help="Force SSL/TLS for REST service")
@click.option("-u", "--dry-run", required=False, default=False)
@click.option("-s", "--secure", required=False, default=False)
@click.option("-pc", "--preshared-cert", required=False, default=False)
@click.option("-v", "--verify", is_flag=True, help="Verify SSL/TLS for REST service")
@click.option("-c", "--preferred-combiner", required=False, type=str, default="", help="url to the combiner or name of the preferred combiner")
@click.option("-va", "--validator", required=False, default=True)
@click.option("-tr", "--trainer", required=False, default=True)
@click.option("-in", "--init", required=False, default=None, help="Set to a filename to (re)init client from file state.")
@click.option("-l", "--logfile", required=False, default=None, help="Set logfile for client log to file.")
@click.option("--heartbeat-interval", required=False, default=2)
@click.option("--reconnect-after-missed-heartbeat", required=False, default=30)
@click.option("--verbosity", required=False, default="INFO", type=click.Choice(["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"], case_sensitive=False))
@click.pass_context
def client_cmd(
ctx,
discoverhost,
discoverport,
token,
name,
client_id,
local_package,
force_ssl,
dry_run,
secure,
preshared_cert,
verify,
preferred_combiner,
validator,
trainer,
init,
logfile,
heartbeat_interval,
reconnect_after_missed_heartbeat,
verbosity,
):
""":param ctx:
:param discoverhost:
:param discoverport:
:param token:
:param name:
:param client_id:
:param remote:
:param dry_run:
:param secure:
:param preshared_cert:
:param verify_cert:
:param preferred_combiner:
:param init:
:param logfile:
:param hearbeat_interval
:param reconnect_after_missed_heartbeat
:param verbosity
:return:
"""
remote = False if local_package else True
config = {
"discover_host": discoverhost,
"discover_port": discoverport,
"token": token,
"name": name,
"client_id": client_id,
"remote_compute_context": remote,
"force_ssl": force_ssl,
"dry_run": dry_run,
"secure": secure,
"preshared_cert": preshared_cert,
"verify": verify,
"preferred_combiner": preferred_combiner,
"validator": validator,
"trainer": trainer,
"logfile": logfile,
"heartbeat_interval": heartbeat_interval,
"reconnect_after_missed_heartbeat": reconnect_after_missed_heartbeat,
"verbosity": verbosity,
}

click.echo(
click.style("\n*** fedn run client is deprecated and will be removed. Please use fedn client start instead. ***\n", blink=True, bold=True, fg="red")
)

if init:
apply_config(init, config)
click.echo(f"\nClient configuration loaded from file: {init}")
click.echo("Values set in file override defaults and command line arguments...\n")
try:
validate_client_config(config)
except InvalidClientConfig as e:
click.echo(f"Error: {e}")
return

client = Client(config)
client.run()


@run_cmd.command("combiner")
@click.option("-d", "--discoverhost", required=False, help="Hostname for discovery services (reducer).")
@click.option("-p", "--discoverport", required=False, help="Port for discovery services (reducer).")
Expand Down
5 changes: 5 additions & 0 deletions fedn/common/settings-controller.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ statestore:
password: password
host: localhost
port: 6534
postgres_config:
username: fedn_admin
password: password
host: fedn_postgres
port: 5432

storage:
storage_type: S3
Expand Down
2 changes: 1 addition & 1 deletion fedn/network/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def get_package_checksum(self):
:return: The checksum.
:rtype: dict
"""
response = requests.get(self._get_url("get_package_checksum"), verify=self.verify, headers=self.headers)
response = requests.get(self._get_url_api_v1("packages/checksum"), verify=self.verify, headers=self.headers)

_json = response.json()

Expand Down
Loading
Loading