diff --git a/.gitignore b/.gitignore
index 5dd71aa..f5d6e64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -266,3 +266,4 @@ tags
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
main.py
hsman/.flaskenv
+hsman/docker.env
diff --git a/hsapi/LICENSE b/hsapi/LICENSE
deleted file mode 100644
index e142a52..0000000
--- a/hsapi/LICENSE
+++ /dev/null
@@ -1,625 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-
-Version 3, 29 June 2007
-
-Copyright © 2007 Free Software Foundation, Inc.
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The GNU General Public License is a free, copyleft license for software and
-other kinds of works.
-
-The licenses for most software and other practical works are designed to take
-away your freedom to share and change the works. By contrast, the GNU General
-Public License is intended to guarantee your freedom to share and change all
-versions of a program--to make sure it remains free software for all its users.
-We, the Free Software Foundation, use the GNU General Public License for most
-of our software; it applies also to any other work released this way by its
-authors. You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom
-to distribute copies of free software (and charge for them if you wish), that
-you receive source code or can get it if you want it, that you can change
-the software or use pieces of it in new free programs, and that you know you
-can do these things.
-
-To protect your rights, we need to prevent others from denying you these rights
-or asking you to surrender the rights. Therefore, you have certain responsibilities
-if you distribute copies of the software, or if you modify it: responsibilities
-to respect the freedom of others.
-
-For example, if you distribute copies of such a program, whether gratis or
-for a fee, you must pass on to the recipients the same freedoms that you received.
-You must make sure that they, too, receive or can get the source code. And
-you must show them these terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps: (1) assert
-copyright on the software, and (2) offer you this License giving you legal
-permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains that
-there is no warranty for this free software. For both users' and authors'
-sake, the GPL requires that modified versions be marked as changed, so that
-their problems will not be attributed erroneously to authors of previous versions.
-
-Some devices are designed to deny users access to install or run modified
-versions of the software inside them, although the manufacturer can do so.
-This is fundamentally incompatible with the aim of protecting users' freedom
-to change the software. The systematic pattern of such abuse occurs in the
-area of products for individuals to use, which is precisely where it is most
-unacceptable. Therefore, we have designed this version of the GPL to prohibit
-the practice for those products. If such problems arise substantially in other
-domains, we stand ready to extend this provision to those domains in future
-versions of the GPL, as needed to protect the freedom of users.
-
-Finally, every program is threatened constantly by software patents. States
-should not allow patents to restrict development and use of software on general-purpose
-computers, but in those that do, we wish to avoid the special danger that
-patents applied to a free program could make it effectively proprietary. To
-prevent this, the GPL assures that patents cannot be used to render the program
-non-free.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
-"Copyright" also means copyright-like laws that apply to other kinds of works,
-such as semiconductor masks.
-
-"The Program" refers to any copyrightable work licensed under this License.
-Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
-or organizations.
-
-To "modify" a work means to copy from or adapt all or part of the work in
-a fashion requiring copyright permission, other than the making of an exact
-copy. The resulting work is called a "modified version" of the earlier work
-or a work "based on" the earlier work.
-
-A "covered work" means either the unmodified Program or a work based on the
-Program.
-
-To "propagate" a work means to do anything with it that, without permission,
-would make you directly or secondarily liable for infringement under applicable
-copyright law, except executing it on a computer or modifying a private copy.
-Propagation includes copying, distribution (with or without modification),
-making available to the public, and in some countries other activities as
-well.
-
-To "convey" a work means any kind of propagation that enables other parties
-to make or receive copies. Mere interaction with a user through a computer
-network, with no transfer of a copy, is not conveying.
-
-An interactive user interface displays "Appropriate Legal Notices" to the
-extent that it includes a convenient and prominently visible feature that
-(1) displays an appropriate copyright notice, and (2) tells the user that
-there is no warranty for the work (except to the extent that warranties are
-provided), that licensees may convey the work under this License, and how
-to view a copy of this License. If the interface presents a list of user commands
-or options, such as a menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
-The "source code" for a work means the preferred form of the work for making
-modifications to it. "Object code" means any non-source form of a work.
-
-A "Standard Interface" means an interface that either is an official standard
-defined by a recognized standards body, or, in the case of interfaces specified
-for a particular programming language, one that is widely used among developers
-working in that language.
-
-The "System Libraries" of an executable work include anything, other than
-the work as a whole, that (a) is included in the normal form of packaging
-a Major Component, but which is not part of that Major Component, and (b)
-serves only to enable use of the work with that Major Component, or to implement
-a Standard Interface for which an implementation is available to the public
-in source code form. A "Major Component", in this context, means a major essential
-component (kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to produce
-the work, or an object code interpreter used to run it.
-
-The "Corresponding Source" for a work in object code form means all the source
-code needed to generate, install, and (for an executable work) run the object
-code and to modify the work, including scripts to control those activities.
-However, it does not include the work's System Libraries, or general-purpose
-tools or generally available free programs which are used unmodified in performing
-those activities but which are not part of the work. For example, Corresponding
-Source includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically linked
-subprograms that the work is specifically designed to require, such as by
-intimate data communication or control flow between those subprograms and
-other parts of the work.
-
-The Corresponding Source need not include anything that users can regenerate
-automatically from other parts of the Corresponding Source.
-
- The Corresponding Source for a work in source code form is that same work.
-
- 2. Basic Permissions.
-
-All rights granted under this License are granted for the term of copyright
-on the Program, and are irrevocable provided the stated conditions are met.
-This License explicitly affirms your unlimited permission to run the unmodified
-Program. The output from running a covered work is covered by this License
-only if the output, given its content, constitutes a covered work. This License
-acknowledges your rights of fair use or other equivalent, as provided by copyright
-law.
-
-You may make, run and propagate covered works that you do not convey, without
-conditions so long as your license otherwise remains in force. You may convey
-covered works to others for the sole purpose of having them make modifications
-exclusively for you, or provide you with facilities for running those works,
-provided that you comply with the terms of this License in conveying all material
-for which you do not control copyright. Those thus making or running the covered
-works for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of your copyrighted
-material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the conditions
-stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-No covered work shall be deemed part of an effective technological measure
-under any applicable law fulfilling obligations under article 11 of the WIPO
-copyright treaty adopted on 20 December 1996, or similar laws prohibiting
-or restricting circumvention of such measures.
-
-When you convey a covered work, you waive any legal power to forbid circumvention
-of technological measures to the extent such circumvention is effected by
-exercising rights under this License with respect to the covered work, and
-you disclaim any intention to limit operation or modification of the work
-as a means of enforcing, against the work's users, your or third parties'
-legal rights to forbid circumvention of technological measures.
-
- 4. Conveying Verbatim Copies.
-
-You may convey verbatim copies of the Program's source code as you receive
-it, in any medium, provided that you conspicuously and appropriately publish
-on each copy an appropriate copyright notice; keep intact all notices stating
-that this License and any non-permissive terms added in accord with section
-7 apply to the code; keep intact all notices of the absence of any warranty;
-and give all recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey, and you
-may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
-You may convey a work based on the Program, or the modifications to produce
-it from the Program, in the form of source code under the terms of section
-4, provided that you also meet all of these conditions:
-
-a) The work must carry prominent notices stating that you modified it, and
-giving a relevant date.
-
-b) The work must carry prominent notices stating that it is released under
-this License and any conditions added under section 7. This requirement modifies
-the requirement in section 4 to "keep intact all notices".
-
-c) You must license the entire work, as a whole, under this License to anyone
-who comes into possession of a copy. This License will therefore apply, along
-with any applicable section 7 additional terms, to the whole of the work,
-and all its parts, regardless of how they are packaged. This License gives
-no permission to license the work in any other way, but it does not invalidate
-such permission if you have separately received it.
-
-d) If the work has interactive user interfaces, each must display Appropriate
-Legal Notices; however, if the Program has interactive interfaces that do
-not display Appropriate Legal Notices, your work need not make them do so.
-
-A compilation of a covered work with other separate and independent works,
-which are not by their nature extensions of the covered work, and which are
-not combined with it such as to form a larger program, in or on a volume of
-a storage or distribution medium, is called an "aggregate" if the compilation
-and its resulting copyright are not used to limit the access or legal rights
-of the compilation's users beyond what the individual works permit. Inclusion
-of a covered work in an aggregate does not cause this License to apply to
-the other parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
-You may convey a covered work in object code form under the terms of sections
-4 and 5, provided that you also convey the machine-readable Corresponding
-Source under the terms of this License, in one of these ways:
-
-a) Convey the object code in, or embodied in, a physical product (including
-a physical distribution medium), accompanied by the Corresponding Source fixed
-on a durable physical medium customarily used for software interchange.
-
-b) Convey the object code in, or embodied in, a physical product (including
-a physical distribution medium), accompanied by a written offer, valid for
-at least three years and valid for as long as you offer spare parts or customer
-support for that product model, to give anyone who possesses the object code
-either (1) a copy of the Corresponding Source for all the software in the
-product that is covered by this License, on a durable physical medium customarily
-used for software interchange, for a price no more than your reasonable cost
-of physically performing this conveying of source, or (2) access to copy the
-Corresponding Source from a network server at no charge.
-
-c) Convey individual copies of the object code with a copy of the written
-offer to provide the Corresponding Source. This alternative is allowed only
-occasionally and noncommercially, and only if you received the object code
-with such an offer, in accord with subsection 6b.
-
-d) Convey the object code by offering access from a designated place (gratis
-or for a charge), and offer equivalent access to the Corresponding Source
-in the same way through the same place at no further charge. You need not
-require recipients to copy the Corresponding Source along with the object
-code. If the place to copy the object code is a network server, the Corresponding
-Source may be on a different server (operated by you or a third party) that
-supports equivalent copying facilities, provided you maintain clear directions
-next to the object code saying where to find the Corresponding Source. Regardless
-of what server hosts the Corresponding Source, you remain obligated to ensure
-that it is available for as long as needed to satisfy these requirements.
-
-e) Convey the object code using peer-to-peer transmission, provided you inform
-other peers where the object code and Corresponding Source of the work are
-being offered to the general public at no charge under subsection 6d.
-
-A separable portion of the object code, whose source code is excluded from
-the Corresponding Source as a System Library, need not be included in conveying
-the object code work.
-
-A "User Product" is either (1) a "consumer product", which means any tangible
-personal property which is normally used for personal, family, or household
-purposes, or (2) anything designed or sold for incorporation into a dwelling.
-In determining whether a product is a consumer product, doubtful cases shall
-be resolved in favor of coverage. For a particular product received by a particular
-user, "normally used" refers to a typical or common use of that class of product,
-regardless of the status of the particular user or of the way in which the
-particular user actually uses, or expects or is expected to use, the product.
-A product is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent the
-only significant mode of use of the product.
-
-"Installation Information" for a User Product means any methods, procedures,
-authorization keys, or other information required to install and execute modified
-versions of a covered work in that User Product from a modified version of
-its Corresponding Source. The information must suffice to ensure that the
-continued functioning of the modified object code is in no case prevented
-or interfered with solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or specifically
-for use in, a User Product, and the conveying occurs as part of a transaction
-in which the right of possession and use of the User Product is transferred
-to the recipient in perpetuity or for a fixed term (regardless of how the
-transaction is characterized), the Corresponding Source conveyed under this
-section must be accompanied by the Installation Information. But this requirement
-does not apply if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has been installed
-in ROM).
-
-The requirement to provide Installation Information does not include a requirement
-to continue to provide support service, warranty, or updates for a work that
-has been modified or installed by the recipient, or for the User Product in
-which it has been modified or installed. Access to a network may be denied
-when the modification itself materially and adversely affects the operation
-of the network or violates the rules and protocols for communication across
-the network.
-
-Corresponding Source conveyed, and Installation Information provided, in accord
-with this section must be in a format that is publicly documented (and with
-an implementation available to the public in source code form), and must require
-no special password or key for unpacking, reading or copying.
-
- 7. Additional Terms.
-
-"Additional permissions" are terms that supplement the terms of this License
-by making exceptions from one or more of its conditions. Additional permissions
-that are applicable to the entire Program shall be treated as though they
-were included in this License, to the extent that they are valid under applicable
-law. If additional permissions apply only to part of the Program, that part
-may be used separately under those permissions, but the entire Program remains
-governed by this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option remove any
-additional permissions from that copy, or from any part of it. (Additional
-permissions may be written to require their own removal in certain cases when
-you modify the work.) You may place additional permissions on material, added
-by you to a covered work, for which you have or can give appropriate copyright
-permission.
-
-Notwithstanding any other provision of this License, for material you add
-to a covered work, you may (if authorized by the copyright holders of that
-material) supplement the terms of this License with terms:
-
-a) Disclaiming warranty or limiting liability differently from the terms of
-sections 15 and 16 of this License; or
-
-b) Requiring preservation of specified reasonable legal notices or author
-attributions in that material or in the Appropriate Legal Notices displayed
-by works containing it; or
-
-c) Prohibiting misrepresentation of the origin of that material, or requiring
-that modified versions of such material be marked in reasonable ways as different
-from the original version; or
-
-d) Limiting the use for publicity purposes of names of licensors or authors
-of the material; or
-
-e) Declining to grant rights under trademark law for use of some trade names,
-trademarks, or service marks; or
-
-f) Requiring indemnification of licensors and authors of that material by
-anyone who conveys the material (or modified versions of it) with contractual
-assumptions of liability to the recipient, for any liability that these contractual
-assumptions directly impose on those licensors and authors.
-
-All other non-permissive additional terms are considered "further restrictions"
-within the meaning of section 10. If the Program as you received it, or any
-part of it, contains a notice stating that it is governed by this License
-along with a term that is a further restriction, you may remove that term.
-If a license document contains a further restriction but permits relicensing
-or conveying under this License, you may add to a covered work material governed
-by the terms of that license document, provided that the further restriction
-does not survive such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you must place,
-in the relevant source files, a statement of the additional terms that apply
-to those files, or a notice indicating where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the form
-of a separately written license, or stated as exceptions; the above requirements
-apply either way.
-
- 8. Termination.
-
-You may not propagate or modify a covered work except as expressly provided
-under this License. Any attempt otherwise to propagate or modify it is void,
-and will automatically terminate your rights under this License (including
-any patent licenses granted under the third paragraph of section 11).
-
-However, if you cease all violation of this License, then your license from
-a particular copyright holder is reinstated (a) provisionally, unless and
-until the copyright holder explicitly and finally terminates your license,
-and (b) permanently, if the copyright holder fails to notify you of the violation
-by some reasonable means prior to 60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is reinstated permanently
-if the copyright holder notifies you of the violation by some reasonable means,
-this is the first time you have received notice of violation of this License
-(for any work) from that copyright holder, and you cure the violation prior
-to 30 days after your receipt of the notice.
-
-Termination of your rights under this section does not terminate the licenses
-of parties who have received copies or rights from you under this License.
-If your rights have been terminated and not permanently reinstated, you do
-not qualify to receive new licenses for the same material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
-You are not required to accept this License in order to receive or run a copy
-of the Program. Ancillary propagation of a covered work occurring solely as
-a consequence of using peer-to-peer transmission to receive a copy likewise
-does not require acceptance. However, nothing other than this License grants
-you permission to propagate or modify any covered work. These actions infringe
-copyright if you do not accept this License. Therefore, by modifying or propagating
-a covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
-Each time you convey a covered work, the recipient automatically receives
-a license from the original licensors, to run, modify and propagate that work,
-subject to this License. You are not responsible for enforcing compliance
-by third parties with this License.
-
-An "entity transaction" is a transaction transferring control of an organization,
-or substantially all assets of one, or subdividing an organization, or merging
-organizations. If propagation of a covered work results from an entity transaction,
-each party to that transaction who receives a copy of the work also receives
-whatever licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the Corresponding
-Source of the work from the predecessor in interest, if the predecessor has
-it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the rights
-granted or affirmed under this License. For example, you may not impose a
-license fee, royalty, or other charge for exercise of rights granted under
-this License, and you may not initiate litigation (including a cross-claim
-or counterclaim in a lawsuit) alleging that any patent claim is infringed
-by making, using, selling, offering for sale, or importing the Program or
-any portion of it.
-
- 11. Patents.
-
-A "contributor" is a copyright holder who authorizes use under this License
-of the Program or a work on which the Program is based. The work thus licensed
-is called the contributor's "contributor version".
-
-A contributor's "essential patent claims" are all patent claims owned or controlled
-by the contributor, whether already acquired or hereafter acquired, that would
-be infringed by some manner, permitted by this License, of making, using,
-or selling its contributor version, but do not include claims that would be
-infringed only as a consequence of further modification of the contributor
-version. For purposes of this definition, "control" includes the right to
-grant patent sublicenses in a manner consistent with the requirements of this
-License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent
-license under the contributor's essential patent claims, to make, use, sell,
-offer for sale, import and otherwise run, modify and propagate the contents
-of its contributor version.
-
-In the following three paragraphs, a "patent license" is any express agreement
-or commitment, however denominated, not to enforce a patent (such as an express
-permission to practice a patent or covenant not to sue for patent infringement).
-To "grant" such a patent license to a party means to make such an agreement
-or commitment not to enforce a patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license, and the
-Corresponding Source of the work is not available for anyone to copy, free
-of charge and under the terms of this License, through a publicly available
-network server or other readily accessible means, then you must either (1)
-cause the Corresponding Source to be so available, or (2) arrange to deprive
-yourself of the benefit of the patent license for this particular work, or
-(3) arrange, in a manner consistent with the requirements of this License,
-to extend the patent license to downstream recipients. "Knowingly relying"
-means you have actual knowledge that, but for the patent license, your conveying
-the covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that country
-that you have reason to believe are valid.
-
-If, pursuant to or in connection with a single transaction or arrangement,
-you convey, or propagate by procuring conveyance of, a covered work, and grant
-a patent license to some of the parties receiving the covered work authorizing
-them to use, propagate, modify or convey a specific copy of the covered work,
-then the patent license you grant is automatically extended to all recipients
-of the covered work and works based on it.
-
-A patent license is "discriminatory" if it does not include within the scope
-of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
-of one or more of the rights that are specifically granted under this License.
-You may not convey a covered work if you are a party to an arrangement with
-a third party that is in the business of distributing software, under which
-you make payment to the third party based on the extent of your activity of
-conveying the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory patent
-license (a) in connection with copies of the covered work conveyed by you
-(or copies made from those copies), or (b) primarily for and in connection
-with specific products or compilations that contain the covered work, unless
-you entered into that arrangement, or that patent license was granted, prior
-to 28 March 2007.
-
-Nothing in this License shall be construed as excluding or limiting any implied
-license or other defenses to infringement that may otherwise be available
-to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
-If conditions are imposed on you (whether by court order, agreement or otherwise)
-that contradict the conditions of this License, they do not excuse you from
-the conditions of this License. If you cannot convey a covered work so as
-to satisfy simultaneously your obligations under this License and any other
-pertinent obligations, then as a consequence you may not convey it at all.
-For example, if you agree to terms that obligate you to collect a royalty
-for further conveying from those to whom you convey the Program, the only
-way you could satisfy both those terms and this License would be to refrain
-entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
-Notwithstanding any other provision of this License, you have permission to
-link or combine any covered work with a work licensed under version 3 of the
-GNU Affero General Public License into a single combined work, and to convey
-the resulting work. The terms of this License will continue to apply to the
-part which is the covered work, but the special requirements of the GNU Affero
-General Public License, section 13, concerning interaction through a network
-will apply to the combination as such.
-
- 14. Revised Versions of this License.
-
-The Free Software Foundation may publish revised and/or new versions of the
-GNU General Public License from time to time. Such new versions will be similar
-in spirit to the present version, but may differ in detail to address new
-problems or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-that a certain numbered version of the GNU General Public License "or any
-later version" applies to it, you have the option of following the terms and
-conditions either of that numbered version or of any later version published
-by the Free Software Foundation. If the Program does not specify a version
-number of the GNU General Public License, you may choose any version ever
-published by the Free Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions of
-the GNU General Public License can be used, that proxy's public statement
-of acceptance of a version permanently authorizes you to choose that version
-for the Program.
-
-Later license versions may give you additional or different permissions. However,
-no additional obligations are imposed on any author or copyright holder as
-a result of your choosing to follow a later version.
-
- 15. Disclaimer of Warranty.
-
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
-LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
-PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
-CORRECTION.
-
- 16. Limitation of Liability.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
-ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
-AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
-INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
-USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
-PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
-If the disclaimer of warranty and limitation of liability provided above cannot
-be given local legal effect according to their terms, reviewing courts shall
-apply local law that most closely approximates an absolute waiver of all civil
-liability in connection with the Program, unless a warranty or assumption
-of liability accompanies a copy of the Program in return for a fee. END OF
-TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible
-use to the public, the best way to achieve this is to make it free software
-which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach
-them to the start of each source file to most effectively state the exclusion
-of warranty; and each file should have at least the "copyright" line and a
-pointer to where the full notice is found.
-
-
-
-Copyright (C)
-
-This program is free software: you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation, either version 3 of the License, or (at your option) any later
-version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short notice like
-this when it starts in an interactive mode:
-
- Copyright (C)
-
-This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-
-This is free software, and you are welcome to redistribute it under certain
-conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands might
-be different; for a GUI interface, you would use an "about box".
-
-You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary. For
-more information on this, and how to apply and follow the GNU GPL, see .
-
-The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General Public
-License instead of this License. But first, please read .
diff --git a/hsapi/headscale.openapi.json b/hsapi/headscale.openapi.json
deleted file mode 100644
index 79f8b92..0000000
--- a/hsapi/headscale.openapi.json
+++ /dev/null
@@ -1,1633 +0,0 @@
-{
- "openapi": "3.0.1",
- "info": {
- "title": "headscale/v1/headscale.proto",
- "version": "version not set"
- },
- "servers": [
- {
- "url": "/"
- }
- ],
- "tags": [
- {
- "name": "HeadscaleService"
- }
- ],
- "paths": {
- "/api/v1/apikey": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ListApiKeys",
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ListApiKeysResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- },
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "summary": "--- ApiKeys start ---",
- "operationId": "HeadscaleService_CreateApiKey",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreateApiKeyRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreateApiKeyResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/apikey/expire": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ExpireApiKey",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ExpireApiKeyRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ExpireApiKeyResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/apikey/{prefix}": {
- "delete": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_DeleteApiKey",
- "parameters": [
- {
- "name": "prefix",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DeleteApiKeyResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/debug/node": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "summary": "--- Node start ---",
- "operationId": "HeadscaleService_DebugCreateNode",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DebugCreateNodeRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DebugCreateNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/node": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ListNodes",
- "parameters": [
- {
- "name": "user",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ListNodesResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/backfillips": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_BackfillNodeIPs",
- "parameters": [
- {
- "name": "confirmed",
- "in": "query",
- "schema": {
- "type": "boolean"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1BackfillNodeIPsResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/register": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_RegisterNode",
- "parameters": [
- {
- "name": "user",
- "in": "query",
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "key",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1RegisterNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/{nodeId}": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_GetNode",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1GetNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- },
- "delete": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_DeleteNode",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DeleteNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/{nodeId}/expire": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ExpireNode",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ExpireNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/{nodeId}/rename/{newName}": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_RenameNode",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- },
- {
- "name": "newName",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1RenameNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/{nodeId}/routes": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_GetNodeRoutes",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1GetNodeRoutesResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/node/{nodeId}/tags": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_SetTags",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HeadscaleServiceSetTagsBody"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1SetTagsResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/node/{nodeId}/user": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_MoveNode",
- "parameters": [
- {
- "name": "nodeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- },
- {
- "name": "user",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1MoveNodeResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/preauthkey": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ListPreAuthKeys",
- "parameters": [
- {
- "name": "user",
- "in": "query",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ListPreAuthKeysResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- },
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "summary": "--- PreAuthKeys start ---",
- "operationId": "HeadscaleService_CreatePreAuthKey",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreatePreAuthKeyRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreatePreAuthKeyResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/preauthkey/expire": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ExpirePreAuthKey",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ExpirePreAuthKeyRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ExpirePreAuthKeyResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/routes": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "summary": "--- Route start ---",
- "operationId": "HeadscaleService_GetRoutes",
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1GetRoutesResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/routes/{routeId}": {
- "delete": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_DeleteRoute",
- "parameters": [
- {
- "name": "routeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DeleteRouteResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/routes/{routeId}/disable": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_DisableRoute",
- "parameters": [
- {
- "name": "routeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DisableRouteResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/routes/{routeId}/enable": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_EnableRoute",
- "parameters": [
- {
- "name": "routeId",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string",
- "format": "uint64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1EnableRouteResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/user": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_ListUsers",
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1ListUsersResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- },
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_CreateUser",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreateUserRequest"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1CreateUserResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- }
- },
- "/api/v1/user/{name}": {
- "get": {
- "tags": [
- "HeadscaleService"
- ],
- "summary": "--- User start ---",
- "operationId": "HeadscaleService_GetUser",
- "parameters": [
- {
- "name": "name",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1GetUserResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- },
- "delete": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_DeleteUser",
- "parameters": [
- {
- "name": "name",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1DeleteUserResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- },
- "/api/v1/user/{oldName}/rename/{newName}": {
- "post": {
- "tags": [
- "HeadscaleService"
- ],
- "operationId": "HeadscaleService_RenameUser",
- "parameters": [
- {
- "name": "oldName",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "name": "newName",
- "in": "path",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "A successful response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/v1RenameUserResponse"
- }
- }
- }
- },
- "default": {
- "description": "An unexpected error response.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/rpcStatus"
- }
- }
- }
- }
- }
- }
- }
- },
- "components": {
- "schemas": {
- "HeadscaleServiceSetTagsBody": {
- "type": "object",
- "properties": {
- "tags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "protobufAny": {
- "type": "object",
- "properties": {
- "@type": {
- "type": "string"
- }
- },
- "additionalProperties": {
- "type": "object"
- }
- },
- "rpcStatus": {
- "type": "object",
- "properties": {
- "code": {
- "type": "integer",
- "format": "int32"
- },
- "message": {
- "type": "string"
- },
- "details": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/protobufAny"
- }
- }
- }
- },
- "v1ApiKey": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string",
- "format": "uint64"
- },
- "prefix": {
- "type": "string"
- },
- "expiration": {
- "type": "string",
- "format": "date-time"
- },
- "createdAt": {
- "type": "string",
- "format": "date-time"
- },
- "lastSeen": {
- "type": "string",
- "format": "date-time"
- }
- }
- },
- "v1BackfillNodeIPsResponse": {
- "type": "object",
- "properties": {
- "changes": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "v1CreateApiKeyRequest": {
- "type": "object",
- "properties": {
- "expiration": {
- "type": "string",
- "format": "date-time"
- }
- }
- },
- "v1CreateApiKeyResponse": {
- "type": "object",
- "properties": {
- "apiKey": {
- "type": "string"
- }
- }
- },
- "v1CreatePreAuthKeyRequest": {
- "type": "object",
- "properties": {
- "user": {
- "type": "string"
- },
- "reusable": {
- "type": "boolean"
- },
- "ephemeral": {
- "type": "boolean"
- },
- "expiration": {
- "type": "string",
- "format": "date-time"
- },
- "aclTags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "v1CreatePreAuthKeyResponse": {
- "type": "object",
- "properties": {
- "preAuthKey": {
- "$ref": "#/components/schemas/v1PreAuthKey"
- }
- }
- },
- "v1CreateUserRequest": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- }
- }
- },
- "v1CreateUserResponse": {
- "type": "object",
- "properties": {
- "user": {
- "$ref": "#/components/schemas/v1User"
- }
- }
- },
- "v1DebugCreateNodeRequest": {
- "type": "object",
- "properties": {
- "user": {
- "type": "string"
- },
- "key": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "routes": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "v1DebugCreateNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1DeleteApiKeyResponse": {
- "type": "object"
- },
- "v1DeleteNodeResponse": {
- "type": "object"
- },
- "v1DeleteRouteResponse": {
- "type": "object"
- },
- "v1DeleteUserResponse": {
- "type": "object"
- },
- "v1DisableRouteResponse": {
- "type": "object"
- },
- "v1EnableRouteResponse": {
- "type": "object"
- },
- "v1ExpireApiKeyRequest": {
- "type": "object",
- "properties": {
- "prefix": {
- "type": "string"
- }
- }
- },
- "v1ExpireApiKeyResponse": {
- "type": "object"
- },
- "v1ExpireNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1ExpirePreAuthKeyRequest": {
- "type": "object",
- "properties": {
- "user": {
- "type": "string"
- },
- "key": {
- "type": "string"
- }
- }
- },
- "v1ExpirePreAuthKeyResponse": {
- "type": "object"
- },
- "v1GetNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1GetNodeRoutesResponse": {
- "type": "object",
- "properties": {
- "routes": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1Route"
- }
- }
- }
- },
- "v1GetRoutesResponse": {
- "type": "object",
- "properties": {
- "routes": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1Route"
- }
- }
- }
- },
- "v1GetUserResponse": {
- "type": "object",
- "properties": {
- "user": {
- "$ref": "#/components/schemas/v1User"
- }
- }
- },
- "v1ListApiKeysResponse": {
- "type": "object",
- "properties": {
- "apiKeys": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1ApiKey"
- }
- }
- }
- },
- "v1ListNodesResponse": {
- "type": "object",
- "properties": {
- "nodes": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- }
- },
- "v1ListPreAuthKeysResponse": {
- "type": "object",
- "properties": {
- "preAuthKeys": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1PreAuthKey"
- }
- }
- }
- },
- "v1ListUsersResponse": {
- "type": "object",
- "properties": {
- "users": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/v1User"
- }
- }
- }
- },
- "v1MoveNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1Node": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string",
- "format": "uint64"
- },
- "machineKey": {
- "type": "string"
- },
- "nodeKey": {
- "type": "string"
- },
- "discoKey": {
- "type": "string"
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "name": {
- "type": "string"
- },
- "user": {
- "$ref": "#/components/schemas/v1User"
- },
- "lastSeen": {
- "type": "string",
- "format": "date-time"
- },
- "expiry": {
- "type": "string",
- "format": "date-time"
- },
- "preAuthKey": {
- "$ref": "#/components/schemas/v1PreAuthKey"
- },
- "createdAt": {
- "type": "string",
- "format": "date-time"
- },
- "registerMethod": {
- "$ref": "#/components/schemas/v1RegisterMethod"
- },
- "forcedTags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "invalidTags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "validTags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "givenName": {
- "type": "string"
- },
- "online": {
- "type": "boolean"
- }
- }
- },
- "v1PreAuthKey": {
- "type": "object",
- "properties": {
- "user": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "key": {
- "type": "string"
- },
- "reusable": {
- "type": "boolean"
- },
- "ephemeral": {
- "type": "boolean"
- },
- "used": {
- "type": "boolean"
- },
- "expiration": {
- "type": "string",
- "format": "date-time"
- },
- "createdAt": {
- "type": "string",
- "format": "date-time"
- },
- "aclTags": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- },
- "v1RegisterMethod": {
- "type": "string",
- "default": "REGISTER_METHOD_UNSPECIFIED",
- "enum": [
- "REGISTER_METHOD_UNSPECIFIED",
- "REGISTER_METHOD_AUTH_KEY",
- "REGISTER_METHOD_CLI",
- "REGISTER_METHOD_OIDC"
- ]
- },
- "v1RegisterNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1RenameNodeResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1RenameUserResponse": {
- "type": "object",
- "properties": {
- "user": {
- "$ref": "#/components/schemas/v1User"
- }
- }
- },
- "v1Route": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string",
- "format": "uint64"
- },
- "node": {
- "$ref": "#/components/schemas/v1Node"
- },
- "prefix": {
- "type": "string"
- },
- "advertised": {
- "type": "boolean"
- },
- "enabled": {
- "type": "boolean"
- },
- "isPrimary": {
- "type": "boolean"
- },
- "createdAt": {
- "type": "string",
- "format": "date-time"
- },
- "updatedAt": {
- "type": "string",
- "format": "date-time"
- },
- "deletedAt": {
- "type": "string",
- "format": "date-time"
- }
- }
- },
- "v1SetTagsResponse": {
- "type": "object",
- "properties": {
- "node": {
- "$ref": "#/components/schemas/v1Node"
- }
- }
- },
- "v1User": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "createdAt": {
- "type": "string",
- "format": "date-time"
- }
- }
- }
- }
- },
- "x-original-swagger-version": "2.0"
-}
\ No newline at end of file
diff --git a/hsapi/hsapi/__init__.py b/hsapi/hsapi/__init__.py
deleted file mode 100644
index 8c4c99b..0000000
--- a/hsapi/hsapi/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from .apikeys import APIKey
-from .nodes import Node
-from .users import User
-from .routes import Route
-from .preauthkeys import PreAuthKey, v1ListPreAuthKeyRequest
diff --git a/hsapi/hsapi/apikeys.py b/hsapi/hsapi/apikeys.py
deleted file mode 100644
index 5336ef4..0000000
--- a/hsapi/hsapi/apikeys.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from pydantic import BaseModel, Field
-from typing import Optional, List
-from datetime import datetime
-
-from .model import HSAPICall
-from .schemas import v1ApiKey
-
-
-class v1CreateApiKeyRequest(BaseModel):
- expiration: str = Field(alias="expiration", default=None)
-
-
-class v1ExpireApiKeyRequest(BaseModel):
- prefix: str = Field(alias="prefix", default=None)
-
-
-class v1ListApiKeysResponse(BaseModel):
- apiKeys: Optional[List[Optional[v1ApiKey]]] = Field(
- alias="apiKeys", default=None)
-
-
-class v1CreateApiKeyResponse(BaseModel):
- apiKey: str = Field(alias="apiKey", default=None)
-
-
-class APIKey(HSAPICall):
-
- objectPath = "apikey"
-
- def list(self) -> v1ListApiKeysResponse:
- response = self.call('get')
- return v1ListApiKeysResponse(**response.json())
-
- def create(self, data: v1CreateApiKeyRequest) -> v1CreateApiKeyResponse:
- response = self.call('post', data=data)
- return v1CreateApiKeyResponse(**response.json())
-
- def expire(self, data: v1ExpireApiKeyRequest) -> None:
- self.call('post', call_path='expire', data=data)
-
- def delete(self, prefix: str) -> None:
- self.call('delete', call_path=prefix)
diff --git a/hsapi/hsapi/config.py b/hsapi/hsapi/config.py
deleted file mode 100644
index 31fed30..0000000
--- a/hsapi/hsapi/config.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-from typing import Union
-
-from pydantic_settings import BaseSettings, SettingsConfigDict
-
-
-class APISettings(BaseSettings):
- model_config = SettingsConfigDict(env_prefix='HSAPI_')
- server: str = "http://localhost:8080"
- api_path: str = "/api/v1"
- api_token: Union[str, None] = None
- ssl_verify: Union[bool, str] = True
-
- def refresh_api_token(self):
- self.api_token = os.environ.get('HSAPI_API_TOKEN', 'default')
-
-
-class HTTPException(Exception):
- def __init__(self, status_code: int, message: str):
- self.status_code = status_code
- self.message = message
- super().__init__(f"{status_code} {message}")
-
- def __str__(self):
- return f"{self.status_code} {self.message}"
diff --git a/hsapi/hsapi/model.py b/hsapi/hsapi/model.py
deleted file mode 100644
index 724272c..0000000
--- a/hsapi/hsapi/model.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from typing import Union, Optional, Dict, Any
-from .config import APISettings, HTTPException
-import requests
-
-
-def formatTags(tagList: Union[list, None] = []) -> list:
- """
- Get a list of tags and prepend `tag:` to all the ones that
- do not start with `tag:`
- """
-
- formattedTags = []
- if tagList:
- for tag in tagList:
- formatted = f"tag:{tag}" if not tag.startswith('tag:') else tag
- formattedTags.append(formatted)
- return formattedTags
-
-
-class HSAPICall:
- """
- Generic API call.
- It has a call() method that wants:
- - a method (GET, POST, DELETE);
- - a subpath, that is appended to /api/v1/{self.objectPath}
- - optional `data` payload, the body of the request
- """
-
- objectPath: str = ""
-
- def __init__(self, settings: Optional[APISettings] = None) -> None:
- self.api_settings = settings if settings else APISettings()
- self.base_path = f"{
- self.api_settings.server}{self.api_settings.api_path}/{self.objectPath}"
-
- def call(self, method, call_path: str = "", data=None, query: dict = {}):
- headers = {
- "Content-Type": "application/json",
- "Accept": "application/json",
- "Authorization": f"Bearer {self.api_settings.api_token}",
- }
-
- json_ = data.dict() if data else dict()
-
- query_params: Dict[str, Any] = {}
- query_params = {key: value for (
- key, value) in query.items() if value is not None}
-
- path = '/'.join([self.base_path, str(call_path)]
- ) if call_path else self.base_path
-
- response = requests.request(
- method,
- path,
- headers=headers,
- params=query_params,
- verify=self.api_settings.ssl_verify,
- json=json_
- )
- if response.status_code != 200:
- raise HTTPException(response.status_code, f" failed. Error: {
- response.text}")
-
- return response
diff --git a/hsapi/hsapi/nodes.py b/hsapi/hsapi/nodes.py
deleted file mode 100644
index 72d6390..0000000
--- a/hsapi/hsapi/nodes.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from .model import HSAPICall, formatTags
-from .schemas import v1Route, v1Node
-from typing import Optional, List
-from pydantic import BaseModel, Field
-
-
-class v1SetTagsNodeRequest(BaseModel):
- tags: Optional[List[str]] = Field(alias="tags", default=None)
-
- def model_post_init(self, ctx):
- self.tags = formatTags(self.tags)
-
-
-class v1MoveNodeRequest(BaseModel):
- user: Optional[str] = Field(alias="user", default=None)
-
-
-class v1BackfillNodeIPsRequest(BaseModel):
- confirmed: Optional[bool] = Field(alias="confirmed", default=True)
-
-
-class v1ListNodesResponse(BaseModel):
- nodes: Optional[List[Optional[v1Node]]] = Field(
- alias="nodes", default=None)
-
-
-class v1NodeResponse(BaseModel):
- node: Optional[v1Node] = Field(alias="node", default=None)
-
-
-class v1GetNodeRoutesResponse(BaseModel):
- routes: Optional[List[Optional[v1Route]]] = Field(
- alias="routes", default=None)
-
-
-class v1BackfillNodeIPsResponse(BaseModel):
- changes: Optional[List[str]] = Field(alias="changes", default=None)
-
-
-class Node(HSAPICall):
-
- objectPath = "node"
-
- def list(self) -> v1ListNodesResponse:
- response = self.call('get')
- return v1ListNodesResponse(**response.json())
-
- def get(self, nodeId: str) -> v1Node:
- # There is a bug in headscale API
- # retrieving a specific node does not return the tags
- # so we get the full list of nodes and extract the node with the
- # ID we want
- # response = self.call('get', call_path=nodeId)
- nodelist = self.list()
- node = [n for n in nodelist.nodes if n.id == nodeId]
- if node:
- return node[0] # type: ignore
- else:
- return v1Node()
-
- def byUser(self, username: str) -> v1ListNodesResponse:
- nodelist = self.list()
-
- byUser = [n for n in nodelist.nodes if n.user.name == username]
-
- return v1ListNodesResponse(nodes=byUser)
-
- def delete(self, nodeId: str) -> None:
- self.call('delete', call_path=nodeId)
-
- def expire(self, nodeId: str) -> None:
- self.call('post', f'{nodeId}/expire')
-
- def rename(self, nodeId: str, newName: str) -> v1NodeResponse:
- response = self.call('post', f'{nodeId}/rename/{newName}')
- return v1NodeResponse(**response.json())
-
- def move(self, nodeId: str, data: v1MoveNodeRequest) -> v1NodeResponse:
- response = self.call('post', f'{nodeId}/user', data)
- return v1NodeResponse(**response.json())
-
- def routes(self, nodeId: str) -> v1GetNodeRoutesResponse:
- response = self.call('get', f'{nodeId}/routes')
- return v1GetNodeRoutesResponse(**response.json())
-
- def setTags(self, nodeId: str, data: v1SetTagsNodeRequest) -> v1NodeResponse:
- response = self.call('post', f'{nodeId}/tags', data)
- return v1NodeResponse(**response.json())
-
- # Broken on server
- def backfillips(self, confirmed: bool = True) -> v1BackfillNodeIPsResponse:
- response = self.call(
- 'post', f'/backfillips?confirmed={confirmed}')
- return v1BackfillNodeIPsResponse(**response.json())
diff --git a/hsapi/hsapi/preauthkeys.py b/hsapi/hsapi/preauthkeys.py
deleted file mode 100644
index 01a4747..0000000
--- a/hsapi/hsapi/preauthkeys.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from typing import Optional, List
-from pydantic import BaseModel, Field
-from .schemas import v1PreAuthKey
-from .model import HSAPICall, formatTags
-
-
-class v1ListPreAuthKeysResponse(BaseModel):
- preAuthKeys: Optional[List[Optional[v1PreAuthKey]]
- ] = Field(alias="preAuthKeys", default=None)
-
-
-class v1PreAuthKeyResponse(BaseModel):
- preAuthKey: Optional[v1PreAuthKey] = Field(
- alias="preAuthKey", default=None)
-
-
-class v1ExpirePreAuthKeyRequest(BaseModel):
- user: str = Field(alias="user", default=None)
- key: str = Field(alias="key", default=None)
-
-
-class v1CreatePreAuthKeyRequest(BaseModel):
- user: str = Field(alias="user", default=None)
- reusable: Optional[bool] = Field(alias="reusable", default=None)
- ephemeral: Optional[bool] = Field(alias="ephemeral", default=None)
- expiration: Optional[str] = Field(alias="expiration", default=None)
- aclTags: Optional[List[str]] = Field(alias="aclTags", default=None)
-
-
-class v1ListPreAuthKeyRequest(BaseModel):
- user: Optional[str] = Field(
- alias="user", default=None)
-
-
-class PreAuthKey(HSAPICall):
-
- objectPath = "preauthkey"
-
- def list(self, data: v1ListPreAuthKeyRequest) -> v1ListPreAuthKeysResponse:
- response = self.call('get', query=data.model_dump())
- return v1ListPreAuthKeysResponse(**response.json())
-
- def create(self, data: v1CreatePreAuthKeyRequest) -> v1PreAuthKeyResponse:
- data.aclTags = formatTags(data.aclTags)
- response = self.call('post', data=data)
- return v1PreAuthKeyResponse(**response.json())
-
- def expire(self, data: v1ExpirePreAuthKeyRequest) -> None:
- self.call('post', data=data)
diff --git a/hsapi/hsapi/routes.py b/hsapi/hsapi/routes.py
deleted file mode 100644
index 145468f..0000000
--- a/hsapi/hsapi/routes.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Optional, List
-from pydantic import BaseModel, Field
-from .model import HSAPICall
-from .schemas import v1Route
-
-
-class v1ListRoutesResponse(BaseModel):
- routes: Optional[List[Optional[v1Route]]] = Field(
- alias="routes", default=None)
-
-
-class Route(HSAPICall):
-
- objectPath = "routes"
-
- def list(self) -> v1ListRoutesResponse:
- response = self.call('get')
- return v1ListRoutesResponse(**response.json())
-
- def delete(self, routeId: str) -> None:
- self.call('delete', call_path=routeId)
-
- def enable(self, routeId: str) -> None:
- self.call('post', f'{routeId}/enable')
-
- def disable(self, routeId: str) -> None:
- self.call('post', f'{routeId}/disable')
diff --git a/hsapi/hsapi/schemas.py b/hsapi/hsapi/schemas.py
deleted file mode 100644
index 3b309a7..0000000
--- a/hsapi/hsapi/schemas.py
+++ /dev/null
@@ -1,104 +0,0 @@
-from typing import Optional, List
-from pydantic import BaseModel, Field, computed_field
-from datetime import datetime, timezone, timedelta
-from enum import Enum
-
-
-class v1RegisterMethod(str, Enum):
-
- REGISTER_METHOD_UNSPECIFIED = "REGISTER_METHOD_UNSPECIFIED"
- REGISTER_METHOD_AUTH_KEY = "REGISTER_METHOD_AUTH_KEY"
- REGISTER_METHOD_CLI = "REGISTER_METHOD_CLI"
- REGISTER_METHOD_OIDC = "REGISTER_METHOD_OIDC"
-
-
-class v1ApiKey(BaseModel):
-
- id: int = Field(alias="id", default=None)
- prefix: str = Field(alias="prefix", default=None)
- expiration: datetime = Field(alias="expiration", default=None)
- createdAt: datetime = Field(alias="createdAt", default=None)
- lastSeen: Optional[datetime] = Field(alias="lastSeen", default=None)
-
- @computed_field
- @property
- def expired(self) -> bool:
- tzinfo = timezone(timedelta(hours=0)) # UTC
- now = datetime.now(tzinfo)
- return self.expiration < now # type: ignore
-
-
-class v1PreAuthKey(BaseModel):
-
- id: int = Field(alias="id", default=None)
- user: str = Field(alias="user", default=None)
- key: str = Field(alias="key", default=None)
- reusable: bool = Field(alias="reusable", default=True)
- ephemeral: bool = Field(alias="ephemeral", default=False)
- used: bool = Field(alias="used", default=None)
- expiration: datetime = Field(alias="expiration", default=None)
- createdAt: datetime = Field(alias="createdAt", default=None)
- aclTags: Optional[List[str]] = Field(alias="aclTags", default=None)
-
- @computed_field
- @property
- def expired(self) -> bool:
- tzinfo = timezone(timedelta(hours=0)) # UTC
- now = datetime.now(tzinfo)
- exptime = self.expiration < now
- expused = not self.reusable and self.used
- expephemereal = self.ephemeral and self.used
- return exptime or expused or expephemereal
-
-
-class v1User(BaseModel):
-
- id: int = Field(alias="id", default=None)
- name: str = Field(alias="name", default=None)
- createdAt: datetime = Field(alias="createdAt", default=None)
-
-
-class v1Node(BaseModel):
- """
- None model
-
- """
-
- id: int = Field(alias="id", default=None)
- machineKey: str = Field(alias="machineKey", default=None)
- nodeKey: str = Field(alias="nodeKey", default=None)
- discoKey: str = Field(alias="discoKey", default=None)
- ipAddresses: List[str] = Field(alias="ipAddresses", default=None)
- name: str = Field(alias="name", default=None)
- user: v1User = Field(alias="user", default=None)
- lastSeen: datetime = Field(alias="lastSeen", default=None)
- expiry: datetime = Field(alias="expiry", default=None)
- preAuthKey: Optional[v1PreAuthKey] = Field(
- alias="preAuthKey", default=None)
-
- createdAt: datetime = Field(alias="createdAt", default=None)
- registerMethod: Optional[v1RegisterMethod] = Field(
- alias="registerMethod", default=None)
-
- forcedTags: Optional[List[str]] = Field(alias="forcedTags", default=None)
- invalidTags: Optional[List[str]] = Field(alias="invalidTags", default=None)
- validTags: Optional[List[str]] = Field(alias="validTags", default=None)
- givenName: str = Field(alias="givenName", default=None)
- online: bool = Field(alias="online", default=None)
-
-
-class v1Route(BaseModel):
- """
- None model
-
- """
-
- id: Optional[int] = Field(alias="id", default=None)
- node: v1Node = Field(alias="node", default=None)
- prefix: str = Field(alias="prefix", default=None)
- advertised: bool = Field(alias="advertised", default=None)
- enabled: bool = Field(alias="enabled", default=None)
- isPrimary: bool = Field(alias="isPrimary", default=None)
- createdAt: datetime = Field(alias="createdAt", default=None)
- updatedAt: datetime = Field(alias="updatedAt", default=None)
- deletedAt: Optional[datetime] = Field(alias="deletedAt", default=None)
diff --git a/hsapi/hsapi/users.py b/hsapi/hsapi/users.py
deleted file mode 100644
index 341152d..0000000
--- a/hsapi/hsapi/users.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from typing import Optional, List
-from pydantic import BaseModel, Field
-from .schemas import v1User
-from .model import HSAPICall
-
-
-class v1CreateUserRequest(BaseModel):
- name: str = Field(alias="name", default=None)
-
-
-class v1ListUsersResponse(BaseModel):
- users: Optional[List[Optional[v1User]]] = Field(
- alias="users", default=None)
-
-
-class v1UserResponse(BaseModel):
- user: Optional[v1User] = Field(alias="user", default=None)
-
-
-class User(HSAPICall):
-
- objectPath = "user"
-
- def list(self) -> v1ListUsersResponse:
- response = self.call('get')
- return v1ListUsersResponse(**response.json())
-
- def get(self, name: str) -> v1UserResponse:
- response = self.call('get', call_path=name)
- return v1UserResponse(**response.json())
-
- def create(self, data: v1CreateUserRequest) -> v1UserResponse:
- response = self.call('post', data=data)
- return v1UserResponse(**response.json())
-
- def delete(self, name: str) -> None:
- self.call('delete', name)
-
- def rename(self, oldName: str, newName: str) -> v1UserResponse:
- response = self.call('post', call_path=f"{oldName}/rename/{newName}")
- return v1UserResponse(**response.json())
diff --git a/hsapi/poetry.lock b/hsapi/poetry.lock
deleted file mode 100644
index cc8c3af..0000000
--- a/hsapi/poetry.lock
+++ /dev/null
@@ -1,330 +0,0 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
-
-[[package]]
-name = "annotated-types"
-version = "0.7.0"
-description = "Reusable constraint types to use with typing.Annotated"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
- {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
-]
-
-[[package]]
-name = "certifi"
-version = "2024.6.2"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"},
- {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.3.2"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.7.0"
-files = [
- {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
- {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
-]
-
-[[package]]
-name = "idna"
-version = "3.7"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
- {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
-]
-
-[[package]]
-name = "pydantic"
-version = "2.7.4"
-description = "Data validation using Python type hints"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"},
- {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"},
-]
-
-[package.dependencies]
-annotated-types = ">=0.4.0"
-pydantic-core = "2.18.4"
-typing-extensions = ">=4.6.1"
-
-[package.extras]
-email = ["email-validator (>=2.0.0)"]
-
-[[package]]
-name = "pydantic-core"
-version = "2.18.4"
-description = "Core functionality for Pydantic validation and serialization"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"},
- {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"},
- {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"},
- {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"},
- {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"},
- {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"},
- {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"},
- {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"},
- {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"},
- {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"},
- {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"},
- {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"},
- {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"},
- {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"},
- {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"},
- {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"},
- {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"},
- {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"},
- {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"},
- {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"},
- {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"},
- {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"},
- {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"},
- {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"},
- {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"},
- {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"},
- {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"},
- {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"},
- {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"},
- {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"},
- {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"},
- {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"},
- {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"},
- {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"},
- {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"},
- {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"},
- {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"},
- {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"},
- {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"},
- {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
-
-[[package]]
-name = "pydantic-settings"
-version = "2.3.4"
-description = "Settings management using Pydantic"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"},
- {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"},
-]
-
-[package.dependencies]
-pydantic = ">=2.7.0"
-python-dotenv = ">=0.21.0"
-
-[package.extras]
-toml = ["tomli (>=2.0.1)"]
-yaml = ["pyyaml (>=6.0.1)"]
-
-[[package]]
-name = "python-dotenv"
-version = "1.0.1"
-description = "Read key-value pairs from a .env file and set them as environment variables"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
- {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
-]
-
-[package.extras]
-cli = ["click (>=5.0)"]
-
-[[package]]
-name = "requests"
-version = "2.32.3"
-description = "Python HTTP for Humans."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
- {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
-]
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
-
-[[package]]
-name = "typing-extensions"
-version = "4.12.2"
-description = "Backported and Experimental Type Hints for Python 3.8+"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
- {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
-]
-
-[[package]]
-name = "urllib3"
-version = "2.2.2"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
- {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-h2 = ["h2 (>=4,<5)"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
-[metadata]
-lock-version = "2.0"
-python-versions = "^3.11"
-content-hash = "28f675747b0ee9850925befb61509ac513e0acc429d7efc1abe2a0fea6d8f97d"
diff --git a/hsapi/pyproject.toml b/hsapi/pyproject.toml
deleted file mode 100644
index 1c235fa..0000000
--- a/hsapi/pyproject.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[tool.poetry]
-name = "hsapi"
-version = "0.9.0"
-description = "Headscale API client"
-authors = ["Andrea Mistrali "]
-license = "BSD"
-readme = "README.md"
-
-[tool.poetry.dependencies]
-python = "^3.11"
-requests = "^2.32.3"
-pydantic = "^2.7.4"
-pydantic-settings = "^2.3.4"
-
-
-[tool.poetry.group.dev.dependencies]
-python-dotenv = "^1.0.1"
-
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
diff --git a/hsman/.dockerbuild.env b/hsman/.dockerbuild.env
new file mode 100644
index 0000000..bad9e13
--- /dev/null
+++ b/hsman/.dockerbuild.env
@@ -0,0 +1 @@
+DOCKERFILE=docker/Dockerfile
diff --git a/hsman/.dockerignore b/hsman/.dockerignore
new file mode 100644
index 0000000..075b7cc
--- /dev/null
+++ b/hsman/.dockerignore
@@ -0,0 +1,3 @@
+build.log
+.flaskenv
+.dockerbuild.env
diff --git a/hsapi/README.md b/hsman/README.md
similarity index 100%
rename from hsapi/README.md
rename to hsman/README.md
diff --git a/hsman/app/__init__.py b/hsman/app/__init__.py
index a20a66f..746b588 100644
--- a/hsman/app/__init__.py
+++ b/hsman/app/__init__.py
@@ -2,7 +2,6 @@ from flask import Flask, render_template
from werkzeug.exceptions import HTTPException
from flask_mobility import Mobility
-# from flask_pyoidc import OIDCAuthentication
from flask_pyoidc.provider_configuration import ProviderConfiguration, ClientMetadata
diff --git a/hsman/app/views.py b/hsman/app/views.py
index c503523..e615ddb 100644
--- a/hsman/app/views.py
+++ b/hsman/app/views.py
@@ -8,10 +8,10 @@ from app import auth
from flask import jsonify
from flask_pyoidc.user_session import UserSession
-from hsapi import Node, User, Route, PreAuthKey
-from hsapi.preauthkeys import (v1ListPreAuthKeyRequest,
- v1CreatePreAuthKeyRequest,
- v1ExpirePreAuthKeyRequest)
+from hsapi_client import Node, User, Route, PreAuthKey
+from hsapi_client.preauthkeys import (v1ListPreAuthKeyRequest,
+ v1CreatePreAuthKeyRequest,
+ v1ExpirePreAuthKeyRequest)
log = logging.getLogger()
diff --git a/hsman/docker/Dockerfile b/hsman/docker/Dockerfile
new file mode 100644
index 0000000..6be579f
--- /dev/null
+++ b/hsman/docker/Dockerfile
@@ -0,0 +1,33 @@
+# syntax = docker/dockerfile:1.2
+FROM python:3.12.2-alpine3.19
+
+ARG APP_VERSION
+ARG APP_SHA
+ARG BUILD_DATE
+
+ENV APP_VERSION=${APP_VERSION:-alpha0}
+ENV APP_SHA=${APP_SHA:-000000}
+# useful in case we want to run in debug mode
+ENV FLASK_APP /hsmon/wsgi.py
+
+RUN apk --update --no-cache add \
+ bash \
+ build-base \
+ libffi-dev \
+ curl && \
+ chmod g+w /run && \
+ pip install poetry gunicorn
+
+COPY . /hsmon
+
+RUN cd hsmon && \
+ poetry install && \
+ poetry export | pip install -r /dev/stdin
+
+
+HEALTHCHECK --interval=20s --timeout=3s CMD curl -I -s -o /dev/null localhost:5000/health || exit 1
+
+EXPOSE 5000
+
+# exectute start up script
+ENTRYPOINT ["/hsmon/docker/entrypoint.sh"]
diff --git a/hsman/docker/entrypoint.sh b/hsman/docker/entrypoint.sh
new file mode 100755
index 0000000..11e2a8f
--- /dev/null
+++ b/hsman/docker/entrypoint.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+if [ $# -gt 0 ]; then
+ exec $*
+fi
+
+echo Starting ${APP_VERSION}
+if [ -e /debug ]; then
+ echo "Running app in debug mode!"
+ export PYTHONPATH=/app/site-packages
+ /hsmon/site-packages/bin/flask run --host 0.0.0.0
+else
+ echo "Running app in production mode!"
+ gunicorn --chdir hsmon wsgi:app -w 1 --threads 2 -b 0.0.0.0:5000
+fi
diff --git a/hsman/gunicorn.conf.py b/hsman/gunicorn.conf.py
new file mode 100644
index 0000000..b17b2ae
--- /dev/null
+++ b/hsman/gunicorn.conf.py
@@ -0,0 +1,17 @@
+wsgi_app = "wsgi:app"
+
+proc_name = "hsmon"
+default_proc_name = "hsmon"
+
+bind = "0.0.0.0:5000"
+workers = 1
+threads = 4
+preload_app = True
+worker_class = "uvicorn.workers.UvicornWorker"
+
+
+logconfig = "logging/production.ini"
+access_log_format = "%(h)s %(l)s %(t)s %(r)s %(s)s %(b)s %(f)s %(a)s"
+# Log to stdout.
+accesslog = "-"
+errorlog = "-"
diff --git a/hsman/poetry.lock b/hsman/poetry.lock
index 4a12d93..661b770 100644
--- a/hsman/poetry.lock
+++ b/hsman/poetry.lock
@@ -42,13 +42,13 @@ files = [
[[package]]
name = "certifi"
-version = "2024.6.2"
+version = "2024.7.4"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
- {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"},
- {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"},
+ {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
+ {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
]
[[package]]
@@ -445,13 +445,14 @@ testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"]
tornado = ["tornado (>=0.2)"]
[[package]]
-name = "hsapi"
+name = "hsapi-client"
version = "0.9.0"
description = "Headscale API client"
optional = false
-python-versions = ">=3.11,<4.0"
+python-versions = "<4.0,>=3.11"
files = [
- {file = "hsapi-0.9.0-py3-none-any.whl", hash = "sha256:51b0a2424d6a93451710129f6232aa1552a83402f59e3e9a2cb7525000886d54"},
+ {file = "hsapi_client-0.9.0-py3-none-any.whl", hash = "sha256:380eabe733f8b22fef38a453d3620deacc32d45a12e1a2f220df6f72434656ca"},
+ {file = "hsapi_client-0.9.0.tar.gz", hash = "sha256:1546af6faf2f64477a288499030cc3eb1055958eeb11bd2599f12e1f39b99c0c"},
]
[package.dependencies]
@@ -459,10 +460,6 @@ pydantic = ">=2.7.4,<3.0.0"
pydantic-settings = ">=2.3.4,<3.0.0"
requests = ">=2.32.3,<3.0.0"
-[package.source]
-type = "file"
-url = "../hsapi/dist/hsapi-0.9.0-py3-none-any.whl"
-
[[package]]
name = "humanize"
version = "4.9.0"
@@ -851,18 +848,18 @@ files = [
[[package]]
name = "pydantic"
-version = "2.8.0"
+version = "2.8.2"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"},
- {file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"},
+ {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"},
+ {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"},
]
[package.dependencies]
annotated-types = ">=0.4.0"
-pydantic-core = "2.20.0"
+pydantic-core = "2.20.1"
typing-extensions = [
{version = ">=4.12.2", markers = "python_version >= \"3.13\""},
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
@@ -873,99 +870,100 @@ email = ["email-validator (>=2.0.0)"]
[[package]]
name = "pydantic-core"
-version = "2.20.0"
+version = "2.20.1"
description = "Core functionality for Pydantic validation and serialization"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"},
- {file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"},
- {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"},
- {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"},
- {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"},
- {file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"},
- {file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"},
- {file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"},
- {file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"},
- {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"},
- {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"},
- {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"},
- {file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"},
- {file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"},
- {file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"},
- {file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"},
- {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"},
- {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"},
- {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"},
- {file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"},
- {file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"},
- {file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"},
- {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"},
- {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"},
- {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"},
- {file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"},
- {file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"},
- {file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"},
- {file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"},
- {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"},
- {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"},
- {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"},
- {file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"},
- {file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"},
- {file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"},
- {file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"},
- {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"},
- {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"},
- {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"},
- {file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"},
- {file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"},
- {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"},
- {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"},
- {file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"},
+ {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"},
+ {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"},
+ {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"},
+ {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"},
+ {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"},
+ {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"},
+ {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"},
+ {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"},
+ {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"},
+ {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"},
+ {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"},
+ {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"},
+ {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"},
+ {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"},
+ {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"},
+ {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"},
+ {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"},
+ {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"},
+ {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"},
+ {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"},
+ {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"},
]
[package.dependencies]
@@ -1159,4 +1157,4 @@ watchdog = ["watchdog (>=2.3)"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.11,<4.0"
-content-hash = "57399db8700fb5bbcdee00cb67fb178f1e7d5bd0b0ef700225ef192bea3a58b6"
+content-hash = "d5dfc1ee9d87ae7860e29f9bdc9f9a6052a648545d4c8f4d543a93e64132944d"
diff --git a/hsman/pyproject.toml b/hsman/pyproject.toml
index daf8cbd..d4b3c24 100644
--- a/hsman/pyproject.toml
+++ b/hsman/pyproject.toml
@@ -11,7 +11,7 @@ python = ">=3.11,<4.0"
Flask = "^3.0.3"
Flask-pyoidc = "^3.14.3"
gunicorn = "^22.0.0"
-hsapi = {path = "../hsapi/dist/hsapi-0.9.0-py3-none-any.whl"}
+hsapi-client = "^0.9.0"
flask-mobility = "^2.0.1"
humanize = "^4.9.0"
flask-pydantic = "^0.12.0"