Skip to content

Commit

Permalink
Merge pull request #150 from pasqal-io/dev
Browse files Browse the repository at this point in the history
[RELEASE] 0.12.5
  • Loading branch information
Augustinio authored Nov 13, 2024
2 parents 8d8cb22 + e948a1a commit 4232e7b
Show file tree
Hide file tree
Showing 16 changed files with 470 additions and 47 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -10,14 +10,14 @@ repos:
- id: check-added-large-files
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.7
rev: v0.6.9
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.3
rev: v8.20.1
hooks:
- id: gitleaks

Expand Down
16 changes: 14 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@

All notable changes to this project will be documented in this file.

## [0.12.5]

_release `2024-11-12`_

### ✨ Added

- Added 'get_batches' method, a feature to retrieve a group of batches based on 'BatchFilters'

### Changed

- Now passing the wrong type for Filtering Jobs or Batches will raise a TypeError instead of a ValueError

## [0.12.4]

_released `2024-10-09`_

### Added
### Added

- Deprecation warnings on init of SDK, now each version of pasqal-cloud is supported for 1 year after release.
If your version is not supported anymore you will get a deprecation warning each time you use the SDK.
Expand All @@ -15,7 +27,7 @@ _released `2024-10-09`_

_released `2024-10-02`_

### Added
### Added

- Allow unauthenticated users to access public device specifications

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SDK to be used to access Pasqal Cloud Services.
| 0.12.2 | 2024-09-11 | 2025-09-11 |
| 0.12.3 | 2024-10-02 | 2025-10-02 |
| 0.12.4 | 2024-10-09 | 2025-10-09 |
| 0.12.5 | 2024-11-12 | 2025-11-12 |

## Installation

Expand Down
90 changes: 80 additions & 10 deletions pasqal_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from pasqal_cloud.job import CreateJob, Job
from pasqal_cloud.utils.constants import JobStatus # noqa: F401
from pasqal_cloud.utils.filters import (
BatchFilters,
CancelJobFilters,
JobFilters,
PaginationParams,
Expand Down Expand Up @@ -274,6 +275,78 @@ def get_batch(self, id: str, fetch_results: bool = False) -> Batch:
self.batches[batch.id] = batch
return batch

def get_batches(
self,
filters: Optional[BatchFilters] = None,
pagination_params: Optional[PaginationParams] = None,
) -> PaginatedResponse:
"""
Retrieve a list of batches matching filters using a pagination system.
Batches are sorted by their creation date in descending order.
If no 'pagination_params' are provided, the first 100 batches
matching the query will be returned by default.
Args:
filters: Filters to be applied to the batches.
pagination_params: Pagination to be applied to the query.
Examples:
>>> get_batches(filters=BatchFilters(status=BatchStatus.ERROR))
Returns the first 100 batches with an ERROR status.
>>> Get_batches(filters=BatchFilters(status=BatchStatus.ERROR),
pagination_params=PaginationParams(offset=100))
Returns batches 101-200 with an ERROR status.
>>> Get_batches(filters=BatchFilters(status=BatchStatus.ERROR),
pagination_params=PaginationParams(offset=200))
Returns batches 201-300 with an ERROR status.
Returns:
PaginatedResponse: Includes the results of the API and some
pagination information.
Raises:
BatchFetchingError: If fetching batches call failed.
TypeError: If `filters` is not an instance of BatchFilters,
or if `pagination_params` is not an instance of PaginationParams.
"""

if pagination_params is None:
pagination_params = PaginationParams()
elif not isinstance(pagination_params, PaginationParams):
raise TypeError(
f"Pagination parameters needs to be a PaginationParams instance, "
f"not a {type(pagination_params)}"
)

if filters is None:
filters = BatchFilters()
elif not isinstance(filters, BatchFilters):
raise TypeError(
f"Filters needs to be a BatchFilters instance, not a {type(filters)}"
)

try:
response = self._client.get_batches(
filters=filters, pagination_params=pagination_params
)
batches = response["data"]
pagination_response = response.get("pagination")
# It should return a pagination all the time
total_nb_batches = (
pagination_response["total"] if pagination_response else 0
)
except HTTPError as e:
raise BatchFetchingError(e) from e
return PaginatedResponse(
total=total_nb_batches,
offset=pagination_params.offset,
results=[Batch(**batch, _client=self._client) for batch in batches],
)

def cancel_batch(self, id: str) -> Batch:
"""Cancel the given batch on the PCS
Expand Down Expand Up @@ -309,7 +382,7 @@ def rebatch(
if filters is None:
filters = RebatchFilters()
elif not isinstance(filters, RebatchFilters):
raise ValueError(
raise TypeError(
f"Filters needs to be a RebatchFilters instance, not a {type(filters)}"
)

Expand Down Expand Up @@ -352,30 +425,27 @@ def get_jobs(
Returns jobs 201-300 with an ERROR status.
Returns:
PaginatedResponse: A class instance with two fields:
- total: An integer representing the total number of jobs
matching the filters.
- results: A list of jobs matching the filters and pagination
parameters provided.
PaginatedResponse: Includes the results of the API and some
pagination information.
Raises:
JobFetchingError: If fetching jobs call failed.
ValueError: If `filters` is not an instance of JobFilters
TypeError: If `filters` is not an instance of JobFilters
or if `pagination_params` is not an instance of PaginationParams.
"""

if pagination_params is None:
pagination_params = PaginationParams()
elif not isinstance(pagination_params, PaginationParams):
raise ValueError(
raise TypeError(
"Pagination parameters needs to be a PaginationParams instance, "
f"not a {type(pagination_params)}"
)

if filters is None:
filters = JobFilters()
elif not isinstance(filters, JobFilters):
raise ValueError(
raise TypeError(
f"Filters needs to be a JobFilters instance, not a {type(filters)}"
)

Expand Down Expand Up @@ -513,7 +583,7 @@ def cancel_jobs(
if filters is None:
filters = CancelJobFilters()
elif not isinstance(filters, CancelJobFilters):
raise ValueError(
raise TypeError(
"Filters needs to be a CancelJobFilters instance, "
f"not a {type(filters)}"
)
Expand Down
4 changes: 2 additions & 2 deletions pasqal_cloud/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
# limitations under the License.


__version__ = "0.12.4"
deprecation_date = "2025-10-09"
__version__ = "0.12.5"
deprecation_date = "2025-11-12"
12 changes: 11 additions & 1 deletion pasqal_cloud/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class Batch(BaseModel):
user_id: str
status: str
_client: Client = PrivateAttr(default=None)
sequence_builder: str
_ordered_jobs: Optional[List[Job]] = PrivateAttr(default=None)
jobs_count: int = 0
jobs_count_per_status: Dict[str, int] = {}
Expand All @@ -92,6 +91,17 @@ def __init__(self, **data: Any) -> None:
Job(**raw_job, _client=self._client) for raw_job in data["jobs"]
]

@property
def sequence_builder(self) -> Optional[str]:
if self._sequence_builder is None:
batch_response = self._client.get_batch(self.id)
self.sequence_builder = batch_response["sequence_builder"]
return self._sequence_builder

@sequence_builder.setter
def sequence_builder(self, value: Any) -> None:
self._sequence_builder = value

@property
def ordered_jobs(self) -> List[Job]:
if self._ordered_jobs is None:
Expand Down
13 changes: 13 additions & 0 deletions pasqal_cloud/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
)
from pasqal_cloud.endpoints import Auth0Conf, Endpoints
from pasqal_cloud.utils.filters import (
BatchFilters,
CancelJobFilters,
JobFilters,
PaginationParams,
Expand Down Expand Up @@ -287,6 +288,18 @@ def get_jobs(
)
return response

def get_batches(
self, filters: BatchFilters, pagination_params: PaginationParams
) -> JSendPayload:
filters_params = filters.model_dump(exclude_unset=True)
filters_params.update(pagination_params.model_dump())
response: JSendPayload = self._authenticated_request(
"GET",
f"{self.endpoints.core}/api/v1/batches",
params=filters_params,
)
return response

def add_jobs(
self, batch_id: str, jobs_data: Sequence[Mapping[str, Any]]
) -> Dict[str, Any]:
Expand Down
24 changes: 24 additions & 0 deletions pasqal_cloud/utils/constants.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
from enum import Enum


class BatchStatus(Enum):
PENDING = "PENDING"
RUNNING = "RUNNING"
DONE = "DONE"
ERROR = "ERROR"
CANCELED = "CANCELED"
TIMED_OUT = "TIMED_OUT"


class JobStatus(Enum):
PENDING = "PENDING"
RUNNING = "RUNNING"
DONE = "DONE"
ERROR = "ERROR"
CANCELED = "CANCELED"


class QueuePriority(Enum):
"""
Values represent the queue a value will be written to, each priority
represents the order of preference batches will be executed.
HIGH being the quickest
MEDIUM being a lower tier
LOW being the lowest tier
"""

LOW = "LOW"
MEDIUM = "MEDIUM"
HIGH = "HIGH"
Loading

0 comments on commit 4232e7b

Please sign in to comment.