primitive 0.1.5__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {primitive-0.1.5 → primitive-0.1.8}/PKG-INFO +1 -1
  2. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/__about__.py +1 -1
  3. primitive-0.1.8/src/primitive/agent/actions.py +71 -0
  4. primitive-0.1.8/src/primitive/agent/commands.py +13 -0
  5. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/cli.py +2 -0
  6. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/client.py +2 -0
  7. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/hardware/actions.py +65 -1
  8. primitive-0.1.8/src/primitive/projects/actions.py +158 -0
  9. primitive-0.1.5/src/primitive/projects/actions.py +0 -55
  10. {primitive-0.1.5 → primitive-0.1.8}/.git-hooks/pre-commit +0 -0
  11. {primitive-0.1.5 → primitive-0.1.8}/.gitattributes +0 -0
  12. {primitive-0.1.5 → primitive-0.1.8}/.github/workflows/lint.yml +0 -0
  13. {primitive-0.1.5 → primitive-0.1.8}/.github/workflows/publish.yml +0 -0
  14. {primitive-0.1.5 → primitive-0.1.8}/.gitignore +0 -0
  15. {primitive-0.1.5 → primitive-0.1.8}/.vscode/settings.json +0 -0
  16. {primitive-0.1.5 → primitive-0.1.8}/LICENSE.txt +0 -0
  17. {primitive-0.1.5 → primitive-0.1.8}/Makefile +0 -0
  18. {primitive-0.1.5 → primitive-0.1.8}/README.md +0 -0
  19. {primitive-0.1.5 → primitive-0.1.8}/linux setup.md +0 -0
  20. {primitive-0.1.5 → primitive-0.1.8}/pyproject.toml +0 -0
  21. {primitive-0.1.5 → primitive-0.1.8}/requirements.txt +0 -0
  22. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/__init__.py +0 -0
  23. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/auth/__init__.py +0 -0
  24. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/auth/actions.py +0 -0
  25. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/auth/commands.py +0 -0
  26. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/files/actions.py +0 -0
  27. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/files/commands.py +0 -0
  28. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/graphql/__init__.py +0 -0
  29. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/graphql/sdk.py +0 -0
  30. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/hardware/commands.py +0 -0
  31. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/lint/actions.py +0 -0
  32. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/lint/commands.py +0 -0
  33. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/projects/__init__.py +0 -0
  34. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/simulations/__init__.py +0 -0
  35. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/simulations/actions.py +0 -0
  36. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/actions.py +0 -0
  37. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/config.py +0 -0
  38. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/files.py +0 -0
  39. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/git.py +0 -0
  40. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/memory_size.py +0 -0
  41. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/printer.py +0 -0
  42. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/shell.py +0 -0
  43. {primitive-0.1.5 → primitive-0.1.8}/src/primitive/utils/verible.py +0 -0
  44. {primitive-0.1.5 → primitive-0.1.8}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: primitive
3
- Version: 0.1.5
3
+ Version: 0.1.8
4
4
  Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
5
5
  Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
6
6
  Project-URL: Source, https://github.com//primitivecorp/primitive-cli
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Dylan Stein <dylan@steins.studio>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.1.5"
4
+ __version__ = "0.1.8"
@@ -0,0 +1,71 @@
1
+ import sys
2
+ from time import sleep
3
+ from primitive.utils.actions import BaseAction
4
+ from loguru import logger
5
+ from primitive.__about__ import __version__
6
+
7
+
8
+ class Agent(BaseAction):
9
+ def execute(
10
+ self,
11
+ ):
12
+ logger.enable("primitive")
13
+ logger.info(" [*] primitive")
14
+ logger.info(f" [*] Version: {__version__}")
15
+
16
+ # self.primitive.hardware.update_hardware_system_info()
17
+ self.primitive.hardware.check_in_http()
18
+
19
+ try:
20
+ while True:
21
+ hardware = self.primitive.hardware.get_own_hardware_details()
22
+
23
+ active_reservation_id = None
24
+ if hardware.get("activeReservation"):
25
+ active_reservation_id = hardware["activeReservation"]["id"]
26
+ if not active_reservation_id:
27
+ logger.debug("No active reservation found")
28
+ sleep(5)
29
+ continue
30
+
31
+ job_runs_data = self.primitive.projects.get_job_runs(
32
+ status="pending", first=1, reservation_id=active_reservation_id
33
+ )
34
+
35
+ pending_job_runs = [
36
+ edge["node"] for edge in job_runs_data["jobRuns"]["edges"]
37
+ ]
38
+
39
+ for job_run in pending_job_runs:
40
+ logger.debug("Found pending Job Run")
41
+ logger.debug(f"Job Run ID: {job_run['id']}")
42
+ logger.debug(f"Job Name: {job_run['job']['name']}")
43
+
44
+ if job_run["job"]["slug"] == "lint":
45
+ logger.debug("Executing Lint Job")
46
+
47
+ self.primitive.projects.job_run_update(
48
+ job_run["id"], status="request_completed"
49
+ )
50
+
51
+ result, message = self.primitive.lint.execute()
52
+ if result:
53
+ self.primitive.projects.job_run_update(
54
+ job_run["id"],
55
+ status="request_completed",
56
+ conclusion="success",
57
+ stdout=message,
58
+ )
59
+ else:
60
+ self.primitive.projects.job_run_update(
61
+ job_run["id"],
62
+ status="request_completed",
63
+ conclusion="failure",
64
+ stdout=message,
65
+ )
66
+
67
+ sleep(5)
68
+ except KeyboardInterrupt:
69
+ logger.info(" [*] Stopping primitive...")
70
+ self.primitive.hardware.check_in_http(is_available=False, is_online=False)
71
+ sys.exit()
@@ -0,0 +1,13 @@
1
+ import click
2
+ import typing
3
+
4
+ if typing.TYPE_CHECKING:
5
+ from ..client import Primitive
6
+
7
+
8
+ @click.command("agent")
9
+ @click.pass_context
10
+ def cli(context):
11
+ """agent"""
12
+ primitive: Primitive = context.obj.get("PRIMITIVE")
13
+ primitive.agent.execute()
@@ -7,6 +7,7 @@ from .auth.commands import config_command, whoami_command
7
7
  from .files.commands import cli as file_commands
8
8
  from .hardware.commands import cli as hardware_commands
9
9
  from .lint.commands import cli as lint_commands
10
+ from .agent.commands import cli as agent_commands
10
11
 
11
12
 
12
13
  @click.group()
@@ -55,6 +56,7 @@ cli.add_command(whoami_command, "whoami")
55
56
  cli.add_command(file_commands, "files")
56
57
  cli.add_command(hardware_commands, "hardware")
57
58
  cli.add_command(lint_commands, "lint")
59
+ cli.add_command(agent_commands, "agent")
58
60
 
59
61
  if __name__ == "__main__":
60
62
  cli(obj={})
@@ -7,6 +7,7 @@ from .files.actions import Files
7
7
  from .simulations.actions import Simulations
8
8
  from .hardware.actions import Hardware
9
9
  from .lint.actions import Lint
10
+ from .agent.actions import Agent
10
11
 
11
12
  from loguru import logger
12
13
 
@@ -57,6 +58,7 @@ class Primitive:
57
58
  self.simulations: Simulations = Simulations(self)
58
59
  self.hardware: Hardware = Hardware(self)
59
60
  self.lint: Lint = Lint(self)
61
+ self.agent: Agent = Agent(self)
60
62
 
61
63
  def get_host_config(self):
62
64
  self.full_config = read_config_file()
@@ -4,7 +4,7 @@ import json
4
4
  import platform
5
5
  from shutil import which
6
6
  import subprocess
7
- from typing import Dict, List
7
+ from typing import Dict, List, Optional
8
8
  import click
9
9
  from loguru import logger
10
10
  from primitive.utils.memory_size import MemorySize
@@ -445,3 +445,67 @@ class Hardware(BaseAction):
445
445
  message = " [*] Failed to check in! "
446
446
  logger.error(message)
447
447
  raise exception
448
+
449
+ def get_hardware_list(self, fingerprint: Optional[str] = None):
450
+ query = gql(
451
+ """
452
+ fragment HardwareFragment on Hardware {
453
+ id
454
+ pk
455
+ name
456
+ slug
457
+ createdAt
458
+ updatedAt
459
+ capabilities {
460
+ id
461
+ pk
462
+ }
463
+ activeReservation {
464
+ id
465
+ pk
466
+ }
467
+ }
468
+
469
+ query hardwareList(
470
+ $before: String
471
+ $after: String
472
+ $first: Int
473
+ $last: Int
474
+ $filters: HardwareFilters
475
+ ) {
476
+ hardwareList(
477
+ before: $before
478
+ after: $after
479
+ first: $first
480
+ last: $last
481
+ filters: $filters
482
+ ) {
483
+ totalCount
484
+ edges {
485
+ cursor
486
+ node {
487
+ ...HardwareFragment
488
+ }
489
+ }
490
+ }
491
+ }
492
+ """
493
+ )
494
+
495
+ filters = {}
496
+ if fingerprint:
497
+ filters["fingerprint"] = {"exact": fingerprint}
498
+
499
+ variables = {
500
+ "first": 1,
501
+ "filters": filters,
502
+ }
503
+ result = self.primitive.session.execute(query, variable_values=variables)
504
+ return result
505
+
506
+ def get_own_hardware_details(self):
507
+ hardware_list_data = self.get_hardware_list(
508
+ fingerprint=self.primitive.host_config.get("fingerprint")
509
+ )
510
+ hardware = hardware_list_data.get("hardwareList").get("edges")[0].get("node")
511
+ return hardware
@@ -0,0 +1,158 @@
1
+ from typing import List, Optional
2
+ from gql import gql
3
+
4
+
5
+ from primitive.utils.actions import BaseAction
6
+
7
+
8
+ class Projects(BaseAction):
9
+ def get_job_runs(
10
+ self,
11
+ organization_id: Optional[str] = None,
12
+ project_id: Optional[str] = None,
13
+ job_id: Optional[str] = None,
14
+ reservation_id: Optional[str] = None,
15
+ git_commit_id: Optional[str] = None,
16
+ status: Optional[str] = None,
17
+ conclusion: Optional[str] = None,
18
+ first: Optional[int] = 1,
19
+ last: Optional[int] = None,
20
+ ):
21
+ query = gql(
22
+ """
23
+ fragment PageInfoFragment on PageInfo {
24
+ hasNextPage
25
+ hasPreviousPage
26
+ startCursor
27
+ endCursor
28
+ }
29
+
30
+ fragment JobRunFragment on JobRun {
31
+ id
32
+ pk
33
+ createdAt
34
+ updatedAt
35
+ completedAt
36
+ startedAt
37
+ status
38
+ conclusion
39
+ stdout
40
+ job {
41
+ id
42
+ pk
43
+ slug
44
+ name
45
+ createdAt
46
+ updatedAt
47
+ }
48
+ }
49
+
50
+ query jobRuns(
51
+ $before: String
52
+ $after: String
53
+ $first: Int
54
+ $last: Int
55
+ $filters: JobRunFilters
56
+ $order: JobRunOrder
57
+ ) {
58
+ jobRuns(
59
+ before: $before
60
+ after: $after
61
+ first: $first
62
+ last: $last
63
+ filters: $filters
64
+ order: $order
65
+ ) {
66
+ totalCount
67
+ pageInfo {
68
+ ...PageInfoFragment
69
+ }
70
+ edges {
71
+ cursor
72
+ node {
73
+ ...JobRunFragment
74
+ }
75
+ }
76
+ }
77
+ }
78
+ """
79
+ )
80
+
81
+ filters = {}
82
+ if organization_id:
83
+ filters["organization"] = {"id": organization_id}
84
+ if project_id:
85
+ filters["project"] = {"id": project_id}
86
+ if job_id:
87
+ filters["job"] = {"id": job_id}
88
+ if reservation_id:
89
+ filters["reservation"] = {"id": reservation_id}
90
+ if git_commit_id:
91
+ filters["gitCommit"] = {"id": git_commit_id}
92
+ if status:
93
+ filters["status"] = {"exact": status}
94
+ if conclusion:
95
+ filters["conclusion"] = {"exact": status}
96
+
97
+ variables = {
98
+ "first": first,
99
+ "last": last,
100
+ "filters": filters,
101
+ "order": {
102
+ "createdAt": "DESC",
103
+ },
104
+ }
105
+
106
+ result = self.primitive.session.execute(query, variable_values=variables)
107
+ return result
108
+
109
+ def get_job_run(self, id: str):
110
+ query = gql(
111
+ """
112
+ query jobRun($id: GlobalID!) {
113
+ jobRun(id: $id) {
114
+ id
115
+ organization {
116
+ id
117
+ }
118
+ }
119
+ }
120
+ """
121
+ )
122
+ variables = {"id": id}
123
+ result = self.primitive.session.execute(query, variable_values=variables)
124
+ return result
125
+
126
+ def job_run_update(
127
+ self,
128
+ id: str,
129
+ status: str = None,
130
+ conclusion: str = None,
131
+ stdout: str = None,
132
+ file_ids: Optional[List[str]] = [],
133
+ ):
134
+ mutation = gql(
135
+ """
136
+ mutation jobRunUpdate($input: JobRunUpdateInput!) {
137
+ jobRunUpdate(input: $input) {
138
+ ... on JobRun {
139
+ id
140
+ status
141
+ conclusion
142
+ }
143
+ }
144
+ }
145
+ """
146
+ )
147
+ input = {"id": id}
148
+ if status:
149
+ input["status"] = status
150
+ if conclusion:
151
+ input["conclusion"] = conclusion
152
+ if file_ids and len(file_ids) > 0:
153
+ input["files"] = file_ids
154
+ if stdout:
155
+ input["stdout"] = stdout
156
+ variables = {"input": input}
157
+ result = self.primitive.session.execute(mutation, variable_values=variables)
158
+ return result
@@ -1,55 +0,0 @@
1
- from typing import List, Optional
2
- from gql import gql
3
-
4
-
5
- from primitive.utils.actions import BaseAction
6
-
7
-
8
- class Projects(BaseAction):
9
- def get_job_run(self, id: str):
10
- query = gql(
11
- """
12
- query jobRun($id: GlobalID!) {
13
- jobRun(id: $id) {
14
- id
15
- organization {
16
- id
17
- }
18
- }
19
- }
20
- """
21
- )
22
- variables = {"id": id}
23
- result = self.primitive.session.execute(query, variable_values=variables)
24
- return result
25
-
26
- def job_run_update(
27
- self,
28
- id: str,
29
- status: str = None,
30
- conclusion: str = None,
31
- file_ids: Optional[List[str]] = [],
32
- ):
33
- mutation = gql(
34
- """
35
- mutation jobRunUpdate($input: JobRunUpdateInput!) {
36
- jobRunUpdate(input: $input) {
37
- ... on JobRun {
38
- id
39
- status
40
- conclusion
41
- }
42
- }
43
- }
44
- """
45
- )
46
- input = {"id": id}
47
- if status:
48
- input["status"] = status
49
- if conclusion:
50
- input["conclusion"] = conclusion
51
- if file_ids and len(file_ids) > 0:
52
- input["files"] = file_ids
53
- variables = {"input": input}
54
- result = self.primitive.session.execute(mutation, variable_values=variables)
55
- return result
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes