sfapi-client 0.0.7__tar.gz → 0.0.9__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 (98) hide show
  1. sfapi_client-0.0.9/.github/dependabot.yml +6 -0
  2. sfapi_client-0.0.9/.github/workflows/black.yml +17 -0
  3. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/.github/workflows/mkdocs.yml +3 -3
  4. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/.github/workflows/pypi.yml +4 -4
  5. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/.github/workflows/pytest.yml +2 -2
  6. sfapi_client-0.0.9/.github/workflows/ruff.yml +14 -0
  7. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/PKG-INFO +2 -2
  8. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/gen_examples.py +0 -1
  9. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/pyproject.toml +8 -1
  10. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/requirements-dev.txt +2 -1
  11. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/scripts/run.py +5 -8
  12. sfapi_client-0.0.9/src/sfapi_client/__init__.py +5 -0
  13. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/client.py +8 -3
  14. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/compute.py +5 -10
  15. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/groups.py +6 -5
  16. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/jobs.py +14 -13
  17. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/paths.py +16 -12
  18. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/projects.py +3 -3
  19. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_async/users.py +10 -7
  20. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_models/__init__.py +7 -9
  21. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_monitor.py +3 -3
  22. sfapi_client-0.0.9/src/sfapi_client/_sync/__init__.py +0 -0
  23. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/client.py +7 -3
  24. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/compute.py +5 -10
  25. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/groups.py +6 -5
  26. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/jobs.py +14 -13
  27. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/paths.py +13 -12
  28. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/projects.py +3 -3
  29. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_sync/users.py +9 -7
  30. sfapi_client-0.0.9/src/sfapi_client/client.py +2 -0
  31. sfapi_client-0.0.9/src/sfapi_client/compute.py +3 -0
  32. sfapi_client-0.0.9/src/sfapi_client/groups.py +2 -0
  33. sfapi_client-0.0.9/src/sfapi_client/jobs.py +7 -0
  34. sfapi_client-0.0.9/src/sfapi_client/paths.py +2 -0
  35. sfapi_client-0.0.9/src/sfapi_client/projects.py +2 -0
  36. sfapi_client-0.0.9/src/sfapi_client/resources.py +1 -0
  37. sfapi_client-0.0.9/src/sfapi_client/users.py +2 -0
  38. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/conftest.py +0 -1
  39. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_compute.py +0 -1
  40. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_jobs_async.py +1 -2
  41. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_paths.py +4 -4
  42. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_paths_async.py +4 -6
  43. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_projects.py +0 -2
  44. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_projects_async.py +0 -1
  45. sfapi_client-0.0.7/src/sfapi_client/__init__.py +0 -5
  46. sfapi_client-0.0.7/src/sfapi_client/client.py +0 -2
  47. sfapi_client-0.0.7/src/sfapi_client/compute.py +0 -3
  48. sfapi_client-0.0.7/src/sfapi_client/groups.py +0 -2
  49. sfapi_client-0.0.7/src/sfapi_client/jobs.py +0 -7
  50. sfapi_client-0.0.7/src/sfapi_client/paths.py +0 -2
  51. sfapi_client-0.0.7/src/sfapi_client/projects.py +0 -2
  52. sfapi_client-0.0.7/src/sfapi_client/resources.py +0 -1
  53. sfapi_client-0.0.7/src/sfapi_client/users.py +0 -2
  54. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/.gitignore +0 -0
  55. /sfapi_client-0.0.7/src/sfapi_client/_async/__init__.py → /sfapi_client-0.0.9/.pre-commit-config.yaml +0 -0
  56. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/LEGAL +0 -0
  57. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/LICENSE +0 -0
  58. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/README.md +0 -0
  59. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/community/contributing.md +0 -0
  60. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/examples/check_current_and_past_jobs.ipynb +0 -0
  61. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/examples/getting_bearer_token.ipynb +0 -0
  62. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/examples/run_job_and_check_status.ipynb +0 -0
  63. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/gen_sync.py +0 -0
  64. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/index.md +0 -0
  65. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/javascript/apiselector.js +0 -0
  66. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/quickstart/index.md +0 -0
  67. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/SUMMARY.txt +0 -0
  68. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/client/index.md +0 -0
  69. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/compute/index.md +0 -0
  70. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/exceptions/index.md +0 -0
  71. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/groups/index.md +0 -0
  72. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/jobs/index.md +0 -0
  73. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/paths/index.md +0 -0
  74. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/projects/index.md +0 -0
  75. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/resources/index.md +0 -0
  76. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/docs/reference/async/users/index.md +0 -0
  77. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/mkdocs.yml +0 -0
  78. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/pytest.ini +0 -0
  79. {sfapi_client-0.0.7/src/sfapi_client/_sync → sfapi_client-0.0.9/src/sfapi_client/_async}/__init__.py +0 -0
  80. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_compute.py +0 -0
  81. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_jobs.py +0 -0
  82. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_models/job_status_response_sacct.py +0 -0
  83. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_models/job_status_response_squeue.py +0 -0
  84. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_models/resources.py +0 -0
  85. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/_utils.py +0 -0
  86. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/src/sfapi_client/exceptions.py +0 -0
  87. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_api.py +0 -0
  88. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_api_async.py +0 -0
  89. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_client.py +0 -0
  90. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_client_async.py +0 -0
  91. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_compute_async.py +0 -0
  92. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_groups.py +0 -0
  93. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_groups_async.py +0 -0
  94. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_jobs.py +0 -0
  95. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_resources.py +0 -0
  96. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_resources_async.py +0 -0
  97. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_users.py +0 -0
  98. {sfapi_client-0.0.7 → sfapi_client-0.0.9}/tests/test_users_async.py +0 -0
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip" # See documentation for possible values
4
+ directory: "/" # Location of package manifests
5
+ schedule:
6
+ interval: "daily"
@@ -0,0 +1,17 @@
1
+ name: black
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ jobs:
10
+ black:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: psf/black@23.9.1
15
+ with:
16
+ options: "--check --verbose"
17
+ jupyter: false
@@ -12,11 +12,11 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
  if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')
14
14
  steps:
15
- - uses: actions/checkout@v3
16
- - uses: actions/setup-python@v4
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
17
  with:
18
18
  python-version: 3.x
19
- - uses: actions/cache@v3
19
+ - uses: actions/cache@v4
20
20
  with:
21
21
  key: mkdocs-${{ github.ref }}
22
22
  path: .cache
@@ -13,9 +13,9 @@ jobs:
13
13
  name: Build wheel
14
14
  runs-on: ubuntu-latest
15
15
  steps:
16
- - uses: actions/checkout@v3
16
+ - uses: actions/checkout@v4
17
17
  - name: Set up Python
18
- uses: actions/setup-python@v4
18
+ uses: actions/setup-python@v5
19
19
  with:
20
20
  python-version: "3.x"
21
21
  - name: Install pypa/build
@@ -33,7 +33,7 @@ jobs:
33
33
  --wheel
34
34
  --outdir dist/
35
35
 
36
- - uses: actions/upload-artifact@v3
36
+ - uses: actions/upload-artifact@v4
37
37
  with:
38
38
  name: wheel
39
39
  path: ./dist/
@@ -49,7 +49,7 @@ jobs:
49
49
  id-token: write
50
50
  if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/')
51
51
  steps:
52
- - uses: actions/download-artifact@v3
52
+ - uses: actions/download-artifact@v4
53
53
  with:
54
54
  name: wheel
55
55
  path: dist
@@ -16,9 +16,9 @@ jobs:
16
16
  python-version: ["3.8", "3.9", "3.10", "3.11"]
17
17
 
18
18
  steps:
19
- - uses: actions/checkout@v3
19
+ - uses: actions/checkout@v4
20
20
  - name: Set up Python ${{ matrix.python-version }}
21
- uses: actions/setup-python@v3
21
+ uses: actions/setup-python@v5
22
22
  with:
23
23
  python-version: ${{ matrix.python-version }}
24
24
  - name: Install dependencies
@@ -0,0 +1,14 @@
1
+ name: ruff
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ jobs:
10
+ ruff:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: chartboost/ruff-action@v1
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: sfapi_client
3
- Version: 0.0.7
3
+ Version: 0.0.9
4
4
  Summary: Python client for NERSC SF API
5
5
  Author-email: Chris Harris <cjh@lbl.gov>, Nicholas Tyler <tylern@lbl.gov>
6
6
  License-File: LICENSE
@@ -1,5 +1,4 @@
1
1
  from pathlib import Path
2
- import os
3
2
  import json
4
3
 
5
4
  replace = Path("examples_dev") / "replacement.json"
@@ -32,10 +32,17 @@ classifiers = [
32
32
  exclude = '''
33
33
  (
34
34
  src/sfapi_client/_sync |
35
- src/sfapi_client/_async/_models.py
35
+ src/sfapi_client/_async/_models.py |
36
+ sfapi_client/examples/
36
37
  )
37
38
  '''
38
39
 
40
+ [tool.ruff]
41
+ exclude = [
42
+ "src/sfapi_client/_sync",
43
+ "src/sfapi_client/_async/_models.py"
44
+ ]
45
+
39
46
  [project.optional-dependencies]
40
47
  docs = [
41
48
  "mkdocs-material",
@@ -3,4 +3,5 @@ unasync
3
3
  typer
4
4
  pytest
5
5
  pytest-asyncio
6
- mkdocs-jupyter
6
+ mkdocs-jupyter
7
+ datamodel-code-generator[http]
@@ -1,17 +1,14 @@
1
- import os
2
1
  import re
3
2
  from pathlib import Path
4
3
  import json
5
4
 
6
5
  import typer
7
6
  import unasync
8
- from pathlib import Path
9
7
  from tempfile import TemporaryDirectory
10
8
  from urllib.parse import urlparse
11
9
  from typing import List, Optional
12
10
 
13
11
  from datamodel_code_generator import InputFileType, generate
14
- import typer
15
12
 
16
13
 
17
14
  cli = typer.Typer()
@@ -91,10 +88,10 @@ def run_unasync():
91
88
  # can't determine the type, so we have to patch things up, for now they are all
92
89
  # string based enums.
93
90
  def _to_str_enum(code: str) -> str:
94
- pattern = re.compile(rf"(.*)\(Enum\)(.*)", re.DOTALL)
91
+ pattern = re.compile(r"(.*)\(Enum\)(.*)", re.DOTALL)
95
92
 
96
93
  while pattern.match(code):
97
- code = re.sub(pattern, rf"\1(str, Enum)\2", code)
94
+ code = re.sub(pattern, r"\1(str, Enum)\2", code)
98
95
 
99
96
  return code
100
97
 
@@ -151,9 +148,9 @@ def _from_json(json: Path, class_name: str) -> str:
151
148
 
152
149
 
153
150
  #
154
- # Generate models using datamodel-codegen using OpenAPI spec and a sample JSON job status output.
155
- # Eventually is would be nice to move the job status model into SF API, so cold then just rely
156
- # only on the OpenAPI spec.
151
+ # Generate models using datamodel-codegen using OpenAPI spec and a sample JSON job
152
+ # status output. Eventually is would be nice to move the job status model into SF
153
+ # API, so cold then just rely only on the OpenAPI spec.
157
154
  #
158
155
  @cli.command(name="codegen")
159
156
  def openapimodel_codegen(
@@ -0,0 +1,5 @@
1
+ from .client import AsyncClient # noqa: F401
2
+ from .client import Client # noqa: F401
3
+ from .exceptions import SfApiError # noqa: F401
4
+ from ._models import StatusValue # noqa: F401
5
+ from ._models.resources import Resource # noqa: F401
@@ -12,8 +12,6 @@ from authlib.jose import JsonWebKey
12
12
  from .compute import Machine, AsyncCompute
13
13
  from ..exceptions import SfApiError
14
14
  from .._models import (
15
- JobOutput as JobStatusResponse,
16
- AppRoutersComputeModelsStatus as JobStatus,
17
15
  Changelog as ChangelogItem,
18
16
  Config as ConfItem,
19
17
  Outage,
@@ -256,7 +254,7 @@ class AsyncClient:
256
254
 
257
255
  async def _oauth2_session(self):
258
256
  if self._client_id is None:
259
- raise SfApiError(f"No credentials have been provides")
257
+ raise SfApiError("No credentials have been provides")
260
258
 
261
259
  if self.__oauth2_session is None:
262
260
  # Create a new session if we haven't already
@@ -514,3 +512,10 @@ AsyncProject.model_rebuild()
514
512
  AsyncRemotePath.model_rebuild()
515
513
  AsyncRole.model_rebuild()
516
514
  AsyncGroupMember.model_rebuild()
515
+
516
+ # Ensure that the job models are built, we need to import here to
517
+ # avoid circular imports
518
+ from .jobs import AsyncJobSacct, AsyncJobSqueue # noqa: E402
519
+
520
+ AsyncJobSqueue.model_rebuild()
521
+ AsyncJobSacct.model_rebuild()
@@ -1,13 +1,9 @@
1
- import asyncio
2
1
  from typing import Dict, List, Optional, Union, Callable
3
2
  import json
4
- from enum import Enum
5
- from pydantic import BaseModel, PrivateAttr, ConfigDict
6
- from functools import wraps
7
-
3
+ from pydantic import PrivateAttr, ConfigDict
8
4
  from ..exceptions import SfApiError
9
5
  from .._utils import _ASYNC_SLEEP
10
- from .jobs import AsyncJobSacct, AsyncJobSqueue, AsyncJobSqueue, JobCommand
6
+ from .jobs import AsyncJobSacct, AsyncJobSqueue, JobCommand
11
7
  from .._models import (
12
8
  AppRoutersStatusModelsStatus as ComputeBase,
13
9
  Task,
@@ -26,11 +22,10 @@ Machine.__str__ = lambda self: self.value
26
22
 
27
23
 
28
24
  def check_auth(method: Callable):
29
- @wraps(method)
30
25
  def wrapper(self, *args, **kwargs):
31
26
  if self.client._client_id is None:
32
27
  raise SfApiError(
33
- f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client."
28
+ f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client." # noqa: E501
34
29
  )
35
30
  elif self.status in [StatusValue.unavailable]:
36
31
  raise SfApiError(
@@ -42,7 +37,7 @@ def check_auth(method: Callable):
42
37
 
43
38
 
44
39
  class AsyncCompute(ComputeBase):
45
- client: Optional["AsyncClient"]
40
+ client: Optional["AsyncClient"] # noqa: F821
46
41
  _monitor: AsyncJobMonitor = PrivateAttr()
47
42
 
48
43
  model_config = ConfigDict(arbitrary_types_allowed=True)
@@ -131,7 +126,7 @@ class AsyncCompute(ComputeBase):
131
126
  Job = AsyncJobSacct if (command == JobCommand.sacct) else AsyncJobSqueue
132
127
  jobs = await self._monitor.fetch_jobs(job_type=Job, jobids=[jobid])
133
128
  if len(jobs) == 0:
134
- raise SfApiError(f"Job not found: ${jobid}")
129
+ raise SfApiError(f"Job not found: {jobid}")
135
130
 
136
131
  return jobs[0]
137
132
 
@@ -11,7 +11,7 @@ def check_auth(method: Callable):
11
11
  def wrapper(self, *args, **kwargs):
12
12
  if self._client_id is None:
13
13
  raise SfApiError(
14
- f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client."
14
+ f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client." # noqa: E501
15
15
  )
16
16
  return method(self, *args, **kwargs)
17
17
 
@@ -19,7 +19,7 @@ def check_auth(method: Callable):
19
19
 
20
20
 
21
21
  class AsyncGroupMember(GroupMemberBase):
22
- client: Optional["AsyncClient"]
22
+ client: Optional["AsyncClient"] # noqa: F821
23
23
 
24
24
  model_config = ConfigDict(arbitrary_types_allowed=True)
25
25
 
@@ -30,13 +30,14 @@ class AsyncGroupMember(GroupMemberBase):
30
30
  return await AsyncUser._fetch_user(self.client, self.name)
31
31
 
32
32
 
33
- # Note: We can't use our generated model as we want user => members ( to avoid confusion with User model )
33
+ # Note: We can't use our generated model as we want user => members ( to avoid
34
+ # confusion with User model )
34
35
  class AsyncGroup(BaseModel):
35
36
  """
36
37
  A user group.
37
38
  """
38
39
 
39
- client: Optional["AsyncClient"]
40
+ client: Optional["AsyncClient"] # noqa: F821
40
41
  gid: Optional[int]
41
42
  name: Optional[str]
42
43
  users_: Optional[List[GroupMemberBase]] = Field(..., alias="users")
@@ -114,7 +115,7 @@ class AsyncGroup(BaseModel):
114
115
 
115
116
  @staticmethod
116
117
  @check_auth
117
- async def _fetch_group(client: "AsyncClient", name):
118
+ async def _fetch_group(client: "AsyncClient", name): # noqa: F821
118
119
  response = await client.get(f"account/groups/{name}")
119
120
 
120
121
  json_response = response.json()
@@ -2,14 +2,14 @@ from __future__ import annotations
2
2
  import sys
3
3
  import math
4
4
  from abc import ABC, abstractmethod
5
- from typing import Any, Optional, Dict, List, ClassVar
5
+ from typing import Any, Optional, Dict, List, ClassVar, Union
6
6
  from .._utils import _ASYNC_SLEEP
7
7
  from ..exceptions import SfApiError
8
8
  from .._models.job_status_response_sacct import OutputItem as JobSacctBase
9
9
  from .._models.job_status_response_squeue import OutputItem as JobSqueueBase
10
10
  from .._models import AppRoutersComputeModelsStatus as JobResponseStatus
11
11
 
12
- from pydantic import BaseModel, Field, field_validator
12
+ from pydantic import BaseModel, field_validator
13
13
 
14
14
  from .._jobs import JobCommand
15
15
  from .._jobs import JobStateResponse
@@ -18,7 +18,7 @@ from .._jobs import TERMINAL_STATES
18
18
 
19
19
 
20
20
  async def _fetch_raw_state(
21
- compute: "AsyncCompute",
21
+ compute: "AsyncCompute", # noqa: F821
22
22
  jobids: Optional[List[int]] = None,
23
23
  user: Optional[str] = None,
24
24
  partition: Optional[str] = None,
@@ -55,7 +55,7 @@ async def _fetch_raw_state(
55
55
 
56
56
  async def _fetch_jobs(
57
57
  job_type: Union["AsyncJobSacct", "AsyncJobSqueue"],
58
- compute: "AsyncCompute",
58
+ compute: "AsyncCompute", # noqa: F821
59
59
  jobids: Optional[List[int]] = None,
60
60
  user: Optional[str] = None,
61
61
  partition: Optional[str] = None,
@@ -76,7 +76,7 @@ class AsyncJob(BaseModel, ABC):
76
76
  Models a job submitted to run on a compute resource.
77
77
  """
78
78
 
79
- compute: Optional["AsyncCompute"] = None
79
+ compute: Optional["AsyncCompute"] = None # noqa: F821
80
80
  state: Optional[JobState] = None
81
81
  jobid: Optional[str] = None
82
82
 
@@ -97,7 +97,7 @@ class AsyncJob(BaseModel, ABC):
97
97
  job_state = await self._fetch_state()
98
98
  self._update(job_state)
99
99
 
100
- def _update(self, new_job_state: Any) -> Job:
100
+ def _update(self, new_job_state: Any) -> Job: # noqa: F821
101
101
  for k in new_job_state.model_fields_set:
102
102
  v = getattr(new_job_state, k)
103
103
  setattr(self, k, v)
@@ -129,8 +129,8 @@ class AsyncJob(BaseModel, ABC):
129
129
  """
130
130
  Wait for a job to move into a terminal state.
131
131
 
132
- :param timeout: The maximum time to wait in seconds, the actually wait time will be in
133
- 10 second increments.
132
+ :param timeout: The maximum time to wait in seconds, the actually
133
+ wait time will be in 10 second increments.
134
134
  :raises TimeoutError: if timeout is reached
135
135
  """
136
136
  return await self._wait_until_complete(timeout)
@@ -139,8 +139,8 @@ class AsyncJob(BaseModel, ABC):
139
139
  """
140
140
  Wait for a job to move into running state.
141
141
 
142
- :param timeout: The maximum time to wait in seconds, the actually wait time will be in
143
- 10 second increments.
142
+ :param timeout: The maximum time to wait in seconds, the actually wait
143
+ time will be in 10 second increments.
144
144
  :raises TimeoutError: if timeout if reached
145
145
  """
146
146
  state = await self._wait_until([JobState.RUNNING] + TERMINAL_STATES, timeout)
@@ -155,7 +155,8 @@ class AsyncJob(BaseModel, ABC):
155
155
  """
156
156
  Cancel a running job
157
157
 
158
- :param wait: True, to wait for job be to cancel, otherwise returns when cancellation
158
+ :param wait: True, to wait for job be to cancel, otherwise returns when
159
+ cancellation
159
160
  has been submitted.
160
161
  :type wait: bool
161
162
 
@@ -199,7 +200,7 @@ class AsyncJobSacct(AsyncJob, JobSacctBase):
199
200
  @classmethod
200
201
  async def _fetch_jobs(
201
202
  cls,
202
- compute: "AsyncCompute",
203
+ compute: "AsyncCompute", # noqa: F821
203
204
  jobids: Optional[List[int]] = None,
204
205
  user: Optional[str] = None,
205
206
  partition: Optional[str] = None,
@@ -241,7 +242,7 @@ class AsyncJobSqueue(AsyncJob, JobSqueueBase):
241
242
  @classmethod
242
243
  async def _fetch_jobs(
243
244
  cls,
244
- compute: "AsyncCompute",
245
+ compute: "AsyncCompute", # noqa: F821
245
246
  jobids: Optional[List[int]] = None,
246
247
  user: Optional[str] = None,
247
248
  partition: Optional[str] = None,
@@ -28,7 +28,7 @@ class AsyncRemotePath(PathBase):
28
28
  pathlib and shares some of its interface.
29
29
  """
30
30
 
31
- compute: Optional["AsyncCompute"]
31
+ compute: Optional["AsyncCompute"] # noqa: F821
32
32
  # It would be nice to be able subclass PurePosixPath, however, this
33
33
  # require using private interfaces. So we derive by composition.
34
34
  _path: PurePosixPath = PrivateAttr()
@@ -54,7 +54,7 @@ class AsyncRemotePath(PathBase):
54
54
  return str(self._path)
55
55
 
56
56
  @property
57
- def parent(self) -> "RemotePath":
57
+ def parent(self) -> "RemotePath": # noqa: F821
58
58
  """
59
59
  The parent of the path.
60
60
 
@@ -66,7 +66,7 @@ class AsyncRemotePath(PathBase):
66
66
  return parent_path
67
67
 
68
68
  @property
69
- def parents(self) -> List["RemotePath"]:
69
+ def parents(self) -> List["RemotePath"]: # noqa: F821
70
70
  """
71
71
  The parents of the path.
72
72
 
@@ -139,7 +139,8 @@ class AsyncRemotePath(PathBase):
139
139
  """
140
140
  Download the file contents.
141
141
 
142
- :param binary: indicate if the file should be treated as binary, defaults to False
142
+ :param binary: indicate if the file should be treated as binary, defaults
143
+ to False
143
144
  :raises IsADirectoryError: if path points to a directory.
144
145
  :raises SfApiError:
145
146
  """
@@ -164,8 +165,11 @@ class AsyncRemotePath(PathBase):
164
165
 
165
166
  @staticmethod
166
167
  async def _ls(
167
- compute: "Compute", path, directory=False, filter_dots=True
168
- ) -> List["RemotePath"]:
168
+ compute: "AsyncCompute", # noqa: F821
169
+ path,
170
+ directory=False,
171
+ filter_dots=True, # noqa: F821
172
+ ) -> List["RemotePath"]: # noqa: F821
169
173
  r = await compute.client.get(f"utilities/ls/{compute.name}/{path}")
170
174
 
171
175
  json_response = r.json()
@@ -250,9 +254,9 @@ class AsyncRemotePath(PathBase):
250
254
  upload_path = str(self._path)
251
255
  except SfApiError as ex:
252
256
  # Its a valid use case to add a upload a new file to an exiting directory.
253
- # In this case the is_dir() will raise a SfApiError with "No such file or directory"
254
- # So we check for that and then see if the parent directory exists, if
255
- # it does we can just continue.
257
+ # In this case the is_dir() will raise a SfApiError with
258
+ # "No such file or directory" So we check for that and then see if the
259
+ # parent directory exists, if it does we can just continue.
256
260
  if not _is_no_such(ex):
257
261
  raise
258
262
 
@@ -291,9 +295,9 @@ class AsyncRemotePath(PathBase):
291
295
  raise IsADirectoryError()
292
296
  except SfApiError as ex:
293
297
  # Its a valid use case to add a open a new file to an exiting directory.
294
- # In this case the is_dir() will raise a SfApiError with "No such file or directory"
295
- # So we check for that and then see if the parent directory exists, if
296
- # it does we can just continue.
298
+ # In this case the is_dir() will raise a SfApiError with
299
+ # "No such file or directory" So we check for that and then see if the
300
+ # parent directory exists, if it does we can just continue.
297
301
  if not _is_no_such(ex):
298
302
  raise
299
303
 
@@ -6,18 +6,18 @@ from ..exceptions import SfApiError
6
6
 
7
7
 
8
8
  class AsyncRole(RoleBase):
9
- client: Optional["AsyncClient"]
9
+ client: Optional["AsyncClient"] # noqa: F821
10
10
 
11
11
  model_config = ConfigDict(arbitrary_types_allowed=True)
12
12
 
13
13
 
14
14
  class AsyncProject(ProjectBase):
15
- client: Optional["AsyncClient"]
15
+ client: Optional["AsyncClient"] # noqa: F821
16
16
  name: str = Field(alias="repo_name")
17
17
 
18
18
  model_config = ConfigDict(arbitrary_types_allowed=True)
19
19
 
20
- async def create_group(self, name: str) -> "AsyncGroup":
20
+ async def create_group(self, name: str) -> "AsyncGroup": # noqa: F821
21
21
  """
22
22
  Create a new project.
23
23
  :param name: The project name
@@ -16,7 +16,7 @@ def check_auth(method: Callable):
16
16
  def wrapper(self, *args, **kwargs):
17
17
  if self._client_id is None:
18
18
  raise SfApiError(
19
- f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client."
19
+ f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client." # noqa: E501
20
20
  )
21
21
  return method(self, *args, **kwargs)
22
22
 
@@ -24,13 +24,16 @@ def check_auth(method: Callable):
24
24
 
25
25
 
26
26
  class AsyncUser(UserBase):
27
- client: Optional["AsyncClient"]
27
+ client: Optional["AsyncClient"] # noqa: F821
28
28
 
29
29
  model_config = ConfigDict(arbitrary_types_allowed=True)
30
30
 
31
31
  @staticmethod
32
32
  @check_auth
33
- async def _fetch_user(client: "AsyncClient", username: Optional[str] = None):
33
+ async def _fetch_user(
34
+ client: "AsyncClient", # noqa: F821
35
+ username: Optional[str] = None, # noqa: F821
36
+ ): # noqa: F821
34
37
  url = "account/"
35
38
  if username is not None:
36
39
  url = f"{url}?username={username}"
@@ -42,7 +45,7 @@ class AsyncUser(UserBase):
42
45
 
43
46
  return user
44
47
 
45
- async def groups(self) -> List["AsyncGroup"]:
48
+ async def groups(self) -> List["AsyncGroup"]: # noqa: F821
46
49
  """
47
50
  The groups that the user is a member of.
48
51
 
@@ -52,7 +55,7 @@ class AsyncUser(UserBase):
52
55
  from .groups import AsyncGroup
53
56
 
54
57
  if self.name != (await self.client._user()).name:
55
- raise SfApiError(f"Can only fetch groups for authenticated user.")
58
+ raise SfApiError("Can only fetch groups for authenticated user.")
56
59
 
57
60
  r = await self.client.get("account/groups")
58
61
 
@@ -73,7 +76,7 @@ class AsyncUser(UserBase):
73
76
  :return: the projects
74
77
  """
75
78
  if self.name != (await self.client._user()).name:
76
- raise SfApiError(f"Can only fetch projects for authenticated user.")
79
+ raise SfApiError("Can only fetch projects for authenticated user.")
77
80
 
78
81
  r = await self.client.get("account/projects")
79
82
 
@@ -93,7 +96,7 @@ class AsyncUser(UserBase):
93
96
  :return: the roles
94
97
  """
95
98
  if self.name != (await self.client._user()).name:
96
- raise SfApiError(f"Can only fetch roles for authenticated user.")
99
+ raise SfApiError("Can only fetch roles for authenticated user.")
97
100
 
98
101
  r = await self.client.get("account/roles")
99
102
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: https://api.nersc.gov/api/v1.2/openapi.json
3
- # timestamp: 2023-07-05T20:00:24+00:00
3
+ # timestamp: 2023-10-20T20:57:45+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -87,7 +87,6 @@ class Outage(BaseModel):
87
87
 
88
88
 
89
89
  class PublicHost(str, Enum):
90
- cori = "cori"
91
90
  dtn01 = "dtn01"
92
91
  perlmutter = "perlmutter"
93
92
 
@@ -118,7 +117,6 @@ class StorageStats(BaseModel):
118
117
 
119
118
  class Task(BaseModel):
120
119
  id: str = Field(..., title="Id")
121
- uuid: Optional[str] = Field(None, title="Uuid")
122
120
  status: Optional[str] = Field(None, title="Status")
123
121
  result: Optional[str] = Field(None, title="Result")
124
122
 
@@ -130,12 +128,12 @@ class Tasks(BaseModel):
130
128
  class UserInfo(BaseModel):
131
129
  uid: int = Field(..., title="Uid")
132
130
  name: str = Field(..., title="Name")
133
- firstname: str = Field(..., title="Firstname")
134
- lastname: str = Field(..., title="Lastname")
135
- middlename: str = Field(..., title="Middlename")
136
- workphone: str = Field(..., title="Workphone")
137
- otherPhones: str = Field(..., title="Otherphones")
138
- email: str = Field(..., title="Email")
131
+ firstname: Optional[str] = Field(None, title="Firstname")
132
+ lastname: Optional[str] = Field(None, title="Lastname")
133
+ middlename: Optional[str] = Field(None, title="Middlename")
134
+ workphone: Optional[str] = Field(None, title="Workphone")
135
+ otherPhones: Optional[str] = Field(None, title="Otherphones")
136
+ email: Optional[str] = Field(None, title="Email")
139
137
 
140
138
 
141
139
  class UserStats(BaseModel):
@@ -15,9 +15,9 @@ from ._sync.jobs import _fetch_jobs, JobSacct, JobSqueue
15
15
  # Async monitor that batches request for job state into fewer request by
16
16
  # requesting that state of multiple jobs in a single request to the server.
17
17
  class AsyncJobMonitor:
18
- def __init__(self, compute: "AsyncCompute"):
18
+ def __init__(self, compute: "AsyncCompute"): # noqa: F821
19
19
  self._jobids: Dict[Type, Set[int]] = {}
20
- self._compute: "AsyncCompute" = compute
20
+ self._compute: "AsyncCompute" = compute # noqa: F821
21
21
  self._monitor_task: asyncio.Task = None
22
22
  self._futures: Dict[Type, Future] = {}
23
23
  self._last_job_type_fetched: Type = None
@@ -126,7 +126,7 @@ class JobRequest:
126
126
  # a time and aggregates the waiting requests.
127
127
  #
128
128
  class SyncJobMonitor:
129
- def __init__(self, compute: "Compute"):
129
+ def __init__(self, compute: "Compute"): # noqa: F821
130
130
  self._compute = compute
131
131
  self._requests: Dict[Type, Set[JobRequest]] = {}
132
132
  # Lock to protect access to self._requests
File without changes